From 159ba13426ae5204c93aa7fc76587cd5beb2181f Mon Sep 17 00:00:00 2001 From: Andreas Linde Date: Thu, 20 Jun 2024 18:57:21 +0200 Subject: [PATCH] Fix Current limits not reporting proper values ElectricalConnectionParameterDescription data also may contain power values per phase. To get the current values, the MeasurementDescription data needs to be evaluated and proper measurementIds passed over to filter the parameter data properly --- api/features.go | 2 +- features/internal/electricalconnection.go | 49 ++++++++++----- .../internal/electricalconnection_test.go | 62 +++++++++++++++---- mocks/ElectricalConnectionCommonInterface.go | 37 +++++------ mocks/ElectricalConnectionServerInterface.go | 37 +++++------ usecases/cem/opev/public.go | 18 +++++- usecases/cem/opev/public_test.go | 22 +++++++ usecases/cem/opev/testhelper_test.go | 12 ++++ usecases/cem/oscev/public.go | 18 +++++- usecases/cem/oscev/public_test.go | 22 +++++++ usecases/cem/oscev/testhelper_test.go | 13 ++++ 11 files changed, 226 insertions(+), 66 deletions(-) diff --git a/api/features.go b/api/features.go index 61d735de..506fdd54 100644 --- a/api/features.go +++ b/api/features.go @@ -114,7 +114,7 @@ type ElectricalConnectionCommonInterface interface { float64, float64, float64, error) // Get the min, max, default current limits for each phase - GetPhaseCurrentLimits() ( + GetPhaseCurrentLimits(measDesc []model.MeasurementDescriptionDataType) ( resultMin []float64, resultMax []float64, resultDefault []float64, resultErr error) // Adjust a value to be within the permitted value range diff --git a/features/internal/electricalconnection.go b/features/internal/electricalconnection.go index 239d0a87..295a1aa5 100644 --- a/features/internal/electricalconnection.go +++ b/features/internal/electricalconnection.go @@ -176,7 +176,7 @@ var PhaseNameMapping = []model.ElectricalConnectionPhaseNameType{ model.ElectricalConnectionPhaseNameTypeC} // Get the min, max, default current limits for each phase -func (e *ElectricalConnectionCommon) GetPhaseCurrentLimits() ( +func (e *ElectricalConnectionCommon) GetPhaseCurrentLimits(measurementDescs []model.MeasurementDescriptionDataType) ( resultMin []float64, resultMax []float64, resultDefault []float64, resultErr error) { for _, phaseName := range PhaseNameMapping { // electricalParameterDescription contains the measured phase for each measurementId @@ -184,25 +184,44 @@ func (e *ElectricalConnectionCommon) GetPhaseCurrentLimits() ( AcMeasuredPhases: util.Ptr(phaseName), } elParamDesc, err := e.GetParameterDescriptionsForFilter(filter) - if err != nil || len(elParamDesc) != 1 || elParamDesc[0].ParameterId == nil { + if err != nil || len(elParamDesc) == 0 { continue } - filter1 := model.ElectricalConnectionPermittedValueSetDataType{ - ParameterId: elParamDesc[0].ParameterId, - } - dataMin, dataMax, dataDefault, err := e.GetPermittedValueDataForFilter(filter1) - if err != nil { - continue - } + // check all params and assume there are no phase specific power limits + for _, paramEl := range elParamDesc { + if paramEl.ParameterId == nil || paramEl.MeasurementId == nil { + continue + } + + // check if the measurementId is in measurementDescs + found := false + for _, mDesc := range measurementDescs { + if mDesc.MeasurementId != nil && *mDesc.MeasurementId == *paramEl.MeasurementId { + found = true + break + } + } + if !found { + continue + } + + filter1 := model.ElectricalConnectionPermittedValueSetDataType{ + ParameterId: paramEl.ParameterId, + } + dataMin, dataMax, dataDefault, err := e.GetPermittedValueDataForFilter(filter1) + if err != nil { + continue + } - // Min current data should be derived from min power data - // but as this value is only properly provided via VAS the - // currrent min values can not be trusted. + // Min current data should be derived from min power data + // but as this value is only properly provided via VAS the + // currrent min values can not be trusted. - resultMin = append(resultMin, dataMin) - resultMax = append(resultMax, dataMax) - resultDefault = append(resultDefault, dataDefault) + resultMin = append(resultMin, dataMin) + resultMax = append(resultMax, dataMax) + resultDefault = append(resultDefault, dataDefault) + } } if len(resultMin) == 0 { diff --git a/features/internal/electricalconnection_test.go b/features/internal/electricalconnection_test.go index b7c624bf..a489d217 100644 --- a/features/internal/electricalconnection_test.go +++ b/features/internal/electricalconnection_test.go @@ -23,8 +23,8 @@ type ElectricalConnectionSuite struct { localEntity spineapi.EntityLocalInterface remoteEntity spineapi.EntityRemoteInterface - localFeature spineapi.FeatureLocalInterface - remoteFeature spineapi.FeatureRemoteInterface + localFeature, localMeasFeature spineapi.FeatureLocalInterface + remoteFeature, remoteMeasFeature spineapi.FeatureRemoteInterface localSut, remoteSut *internal.ElectricalConnectionCommon @@ -47,6 +47,12 @@ func (s *ElectricalConnectionSuite) BeforeTest(suiteName, testName string) { model.FunctionTypeElectricalConnectionCharacteristicListData, }, }, + { + featureType: model.FeatureTypeTypeMeasurement, + functions: []model.FunctionType{ + model.FunctionTypeMeasurementDescriptionListData, + }, + }, }, ) @@ -54,11 +60,15 @@ func (s *ElectricalConnectionSuite) BeforeTest(suiteName, testName string) { assert.NotNil(s.T(), s.localFeature) s.localSut = internal.NewLocalElectricalConnection(s.localFeature) assert.NotNil(s.T(), s.localSut) + s.localMeasFeature = s.localEntity.FeatureOfTypeAndRole(model.FeatureTypeTypeMeasurement, model.RoleTypeServer) + assert.NotNil(s.T(), s.localMeasFeature) s.remoteFeature = s.remoteEntity.FeatureOfTypeAndRole(model.FeatureTypeTypeElectricalConnection, model.RoleTypeServer) assert.NotNil(s.T(), s.remoteFeature) s.remoteSut = internal.NewRemoteElectricalConnection(s.remoteFeature) assert.NotNil(s.T(), s.remoteSut) + s.remoteMeasFeature = s.remoteEntity.FeatureOfTypeAndRole(model.FeatureTypeTypeMeasurement, model.RoleTypeServer) + assert.NotNil(s.T(), s.remoteMeasFeature) } func (s *ElectricalConnectionSuite) Test_CheckEventPayloadDataForFilter() { @@ -612,34 +622,34 @@ func (s *ElectricalConnectionSuite) Test_GetCharacteristicForContextType() { } func (s *ElectricalConnectionSuite) Test_EVCurrentLimits() { - minData, maxData, defaultData, err := s.localSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err := s.localSut.GetPhaseCurrentLimits(nil) assert.NotNil(s.T(), err) assert.Nil(s.T(), minData) assert.Nil(s.T(), maxData) assert.Nil(s.T(), defaultData) - minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits(nil) assert.NotNil(s.T(), err) assert.Nil(s.T(), minData) assert.Nil(s.T(), maxData) assert.Nil(s.T(), defaultData) - minData, maxData, defaultData, err = s.localSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.localSut.GetPhaseCurrentLimits(nil) assert.NotNil(s.T(), err) assert.Nil(s.T(), minData) assert.Nil(s.T(), maxData) assert.Nil(s.T(), defaultData) - minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits(nil) assert.NotNil(s.T(), err) assert.Nil(s.T(), minData) assert.Nil(s.T(), maxData) assert.Nil(s.T(), defaultData) - minData, maxData, defaultData, err = s.localSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.localSut.GetPhaseCurrentLimits(nil) assert.NotNil(s.T(), err) assert.Nil(s.T(), minData) assert.Nil(s.T(), maxData) assert.Nil(s.T(), defaultData) - minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits(nil) assert.NotNil(s.T(), err) assert.Nil(s.T(), minData) assert.Nil(s.T(), maxData) @@ -673,18 +683,46 @@ func (s *ElectricalConnectionSuite) Test_EVCurrentLimits() { fErr = s.remoteFeature.UpdateData(model.FunctionTypeElectricalConnectionParameterDescriptionListData, paramData, nil, nil) assert.Nil(s.T(), fErr) - minData, maxData, defaultData, err = s.localSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.localSut.GetPhaseCurrentLimits(nil) assert.NotNil(s.T(), err) assert.Nil(s.T(), minData) assert.Nil(s.T(), maxData) assert.Nil(s.T(), defaultData) - minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits(nil) assert.NotNil(s.T(), err) assert.Nil(s.T(), minData) assert.Nil(s.T(), maxData) assert.Nil(s.T(), defaultData) + measData := &model.MeasurementDescriptionListDataType{ + MeasurementDescriptionData: []model.MeasurementDescriptionDataType{ + { + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent), + CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), + Unit: util.Ptr(model.UnitOfMeasurementTypeA), + ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent), + }, + { + MeasurementId: util.Ptr(model.MeasurementIdType(1)), + MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent), + CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), + Unit: util.Ptr(model.UnitOfMeasurementTypeA), + ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent)}, + { + MeasurementId: util.Ptr(model.MeasurementIdType(2)), + MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent), + CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), + Unit: util.Ptr(model.UnitOfMeasurementTypeA), + ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent)}, + }, + } + fErr = s.localMeasFeature.UpdateData(model.FunctionTypeMeasurementDescriptionListData, measData, nil, nil) + assert.Nil(s.T(), fErr) + fErr = s.remoteMeasFeature.UpdateData(model.FunctionTypeMeasurementDescriptionListData, measData, nil, nil) + assert.Nil(s.T(), fErr) + type permittedStruct struct { defaultExists bool defaultValue, expectedDefaultValue float64 @@ -775,7 +813,7 @@ func (s *ElectricalConnectionSuite) Test_EVCurrentLimits() { fErr = s.remoteFeature.UpdateData(model.FunctionTypeElectricalConnectionPermittedValueSetListData, permData, nil, nil) assert.Nil(s.T(), fErr) - minData, maxData, defaultData, err = s.localSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.localSut.GetPhaseCurrentLimits(measData.MeasurementDescriptionData) assert.Nil(s.T(), err) assert.Equal(s.T(), len(tc.permitted), len(minData)) @@ -787,7 +825,7 @@ func (s *ElectricalConnectionSuite) Test_EVCurrentLimits() { assert.Equal(s.T(), item.expectedDefaultValue, defaultData[index]) } - minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits() + minData, maxData, defaultData, err = s.remoteSut.GetPhaseCurrentLimits(measData.MeasurementDescriptionData) assert.Nil(s.T(), err) assert.Equal(s.T(), len(tc.permitted), len(minData)) diff --git a/mocks/ElectricalConnectionCommonInterface.go b/mocks/ElectricalConnectionCommonInterface.go index ebd24245..6fb44028 100644 --- a/mocks/ElectricalConnectionCommonInterface.go +++ b/mocks/ElectricalConnectionCommonInterface.go @@ -474,9 +474,9 @@ func (_c *ElectricalConnectionCommonInterface_GetPermittedValueSetForFilter_Call return _c } -// GetPhaseCurrentLimits provides a mock function with given fields: -func (_m *ElectricalConnectionCommonInterface) GetPhaseCurrentLimits() ([]float64, []float64, []float64, error) { - ret := _m.Called() +// GetPhaseCurrentLimits provides a mock function with given fields: measDesc +func (_m *ElectricalConnectionCommonInterface) GetPhaseCurrentLimits(measDesc []model.MeasurementDescriptionDataType) ([]float64, []float64, []float64, error) { + ret := _m.Called(measDesc) if len(ret) == 0 { panic("no return value specified for GetPhaseCurrentLimits") @@ -486,35 +486,35 @@ func (_m *ElectricalConnectionCommonInterface) GetPhaseCurrentLimits() ([]float6 var r1 []float64 var r2 []float64 var r3 error - if rf, ok := ret.Get(0).(func() ([]float64, []float64, []float64, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func([]model.MeasurementDescriptionDataType) ([]float64, []float64, []float64, error)); ok { + return rf(measDesc) } - if rf, ok := ret.Get(0).(func() []float64); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func([]model.MeasurementDescriptionDataType) []float64); ok { + r0 = rf(measDesc) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]float64) } } - if rf, ok := ret.Get(1).(func() []float64); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func([]model.MeasurementDescriptionDataType) []float64); ok { + r1 = rf(measDesc) } else { if ret.Get(1) != nil { r1 = ret.Get(1).([]float64) } } - if rf, ok := ret.Get(2).(func() []float64); ok { - r2 = rf() + if rf, ok := ret.Get(2).(func([]model.MeasurementDescriptionDataType) []float64); ok { + r2 = rf(measDesc) } else { if ret.Get(2) != nil { r2 = ret.Get(2).([]float64) } } - if rf, ok := ret.Get(3).(func() error); ok { - r3 = rf() + if rf, ok := ret.Get(3).(func([]model.MeasurementDescriptionDataType) error); ok { + r3 = rf(measDesc) } else { r3 = ret.Error(3) } @@ -528,13 +528,14 @@ type ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call struct { } // GetPhaseCurrentLimits is a helper method to define mock.On call -func (_e *ElectricalConnectionCommonInterface_Expecter) GetPhaseCurrentLimits() *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call { - return &ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call{Call: _e.mock.On("GetPhaseCurrentLimits")} +// - measDesc []model.MeasurementDescriptionDataType +func (_e *ElectricalConnectionCommonInterface_Expecter) GetPhaseCurrentLimits(measDesc interface{}) *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call { + return &ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call{Call: _e.mock.On("GetPhaseCurrentLimits", measDesc)} } -func (_c *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call) Run(run func()) *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call { +func (_c *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call) Run(run func(measDesc []model.MeasurementDescriptionDataType)) *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].([]model.MeasurementDescriptionDataType)) }) return _c } @@ -544,7 +545,7 @@ func (_c *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call) Return return _c } -func (_c *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call) RunAndReturn(run func() ([]float64, []float64, []float64, error)) *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call { +func (_c *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call) RunAndReturn(run func([]model.MeasurementDescriptionDataType) ([]float64, []float64, []float64, error)) *ElectricalConnectionCommonInterface_GetPhaseCurrentLimits_Call { _c.Call.Return(run) return _c } diff --git a/mocks/ElectricalConnectionServerInterface.go b/mocks/ElectricalConnectionServerInterface.go index 2213abfd..888f60a2 100644 --- a/mocks/ElectricalConnectionServerInterface.go +++ b/mocks/ElectricalConnectionServerInterface.go @@ -626,9 +626,9 @@ func (_c *ElectricalConnectionServerInterface_GetPermittedValueSetForFilter_Call return _c } -// GetPhaseCurrentLimits provides a mock function with given fields: -func (_m *ElectricalConnectionServerInterface) GetPhaseCurrentLimits() ([]float64, []float64, []float64, error) { - ret := _m.Called() +// GetPhaseCurrentLimits provides a mock function with given fields: measDesc +func (_m *ElectricalConnectionServerInterface) GetPhaseCurrentLimits(measDesc []model.MeasurementDescriptionDataType) ([]float64, []float64, []float64, error) { + ret := _m.Called(measDesc) if len(ret) == 0 { panic("no return value specified for GetPhaseCurrentLimits") @@ -638,35 +638,35 @@ func (_m *ElectricalConnectionServerInterface) GetPhaseCurrentLimits() ([]float6 var r1 []float64 var r2 []float64 var r3 error - if rf, ok := ret.Get(0).(func() ([]float64, []float64, []float64, error)); ok { - return rf() + if rf, ok := ret.Get(0).(func([]model.MeasurementDescriptionDataType) ([]float64, []float64, []float64, error)); ok { + return rf(measDesc) } - if rf, ok := ret.Get(0).(func() []float64); ok { - r0 = rf() + if rf, ok := ret.Get(0).(func([]model.MeasurementDescriptionDataType) []float64); ok { + r0 = rf(measDesc) } else { if ret.Get(0) != nil { r0 = ret.Get(0).([]float64) } } - if rf, ok := ret.Get(1).(func() []float64); ok { - r1 = rf() + if rf, ok := ret.Get(1).(func([]model.MeasurementDescriptionDataType) []float64); ok { + r1 = rf(measDesc) } else { if ret.Get(1) != nil { r1 = ret.Get(1).([]float64) } } - if rf, ok := ret.Get(2).(func() []float64); ok { - r2 = rf() + if rf, ok := ret.Get(2).(func([]model.MeasurementDescriptionDataType) []float64); ok { + r2 = rf(measDesc) } else { if ret.Get(2) != nil { r2 = ret.Get(2).([]float64) } } - if rf, ok := ret.Get(3).(func() error); ok { - r3 = rf() + if rf, ok := ret.Get(3).(func([]model.MeasurementDescriptionDataType) error); ok { + r3 = rf(measDesc) } else { r3 = ret.Error(3) } @@ -680,13 +680,14 @@ type ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call struct { } // GetPhaseCurrentLimits is a helper method to define mock.On call -func (_e *ElectricalConnectionServerInterface_Expecter) GetPhaseCurrentLimits() *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call { - return &ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call{Call: _e.mock.On("GetPhaseCurrentLimits")} +// - measDesc []model.MeasurementDescriptionDataType +func (_e *ElectricalConnectionServerInterface_Expecter) GetPhaseCurrentLimits(measDesc interface{}) *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call { + return &ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call{Call: _e.mock.On("GetPhaseCurrentLimits", measDesc)} } -func (_c *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call) Run(run func()) *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call { +func (_c *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call) Run(run func(measDesc []model.MeasurementDescriptionDataType)) *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call { _c.Call.Run(func(args mock.Arguments) { - run() + run(args[0].([]model.MeasurementDescriptionDataType)) }) return _c } @@ -696,7 +697,7 @@ func (_c *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call) Return return _c } -func (_c *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call) RunAndReturn(run func() ([]float64, []float64, []float64, error)) *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call { +func (_c *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call) RunAndReturn(run func([]model.MeasurementDescriptionDataType) ([]float64, []float64, []float64, error)) *ElectricalConnectionServerInterface_GetPhaseCurrentLimits_Call { _c.Call.Return(run) return _c } diff --git a/usecases/cem/opev/public.go b/usecases/cem/opev/public.go index d7948b41..53732d67 100644 --- a/usecases/cem/opev/public.go +++ b/usecases/cem/opev/public.go @@ -25,7 +25,23 @@ func (e *OPEV) CurrentLimits(entity spineapi.EntityRemoteInterface) ([]float64, return nil, nil, nil, err } - return ec.GetPhaseCurrentLimits() + meas, err := client.NewMeasurement(e.LocalEntity, entity) + if err != nil { + return nil, nil, nil, err + } + + filter := model.MeasurementDescriptionDataType{ + MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent), + CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), + Unit: util.Ptr(model.UnitOfMeasurementTypeA), + ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent), + } + measDesc, err := meas.GetDescriptionsForFilter(filter) + if err != nil { + return nil, nil, nil, err + } + + return ec.GetPhaseCurrentLimits(measDesc) } // return the current loadcontrol obligation limits diff --git a/usecases/cem/opev/public_test.go b/usecases/cem/opev/public_test.go index a6c94df7..7dd8b38d 100644 --- a/usecases/cem/opev/public_test.go +++ b/usecases/cem/opev/public_test.go @@ -2,6 +2,8 @@ package opev import ( ucapi "github.com/enbility/eebus-go/usecases/api" + "github.com/enbility/ship-go/util" + "github.com/enbility/spine-go/model" "github.com/stretchr/testify/assert" ) @@ -14,6 +16,26 @@ func (s *CemOPEVSuite) Test_Public() { _, _, _, err = s.sut.CurrentLimits(s.evEntity) assert.NotNil(s.T(), err) + meas := s.evEntity.FeatureOfTypeAndRole(model.FeatureTypeTypeMeasurement, model.RoleTypeServer) + assert.NotNil(s.T(), meas) + + mData := &model.MeasurementDescriptionListDataType{ + MeasurementDescriptionData: []model.MeasurementDescriptionDataType{ + { + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent), + CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), + Unit: util.Ptr(model.UnitOfMeasurementTypeA), + ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent), + }, + }, + } + errT := meas.UpdateData(model.FunctionTypeMeasurementDescriptionListData, mData, nil, nil) + assert.Nil(s.T(), errT) + + _, _, _, err = s.sut.CurrentLimits(s.evEntity) + assert.NotNil(s.T(), err) + _, err = s.sut.LoadControlLimits(s.mockRemoteEntity) assert.NotNil(s.T(), err) diff --git a/usecases/cem/opev/testhelper_test.go b/usecases/cem/opev/testhelper_test.go index 517066e1..80ab3c4c 100644 --- a/usecases/cem/opev/testhelper_test.go +++ b/usecases/cem/opev/testhelper_test.go @@ -74,6 +74,13 @@ func (s *CemOPEVSuite) BeforeTest(suiteName, testName string) { s.sut.AddFeatures() s.sut.AddUseCase() + var clientFeatures = []model.FeatureTypeType{ + model.FeatureTypeTypeMeasurement, + } + for _, feature := range clientFeatures { + _ = localEntity.GetOrAddFeature(feature, model.RoleTypeClient) + } + var entities []spineapi.EntityRemoteInterface s.remoteDevice, entities = setupDevices(s.service, s.T()) s.evEntity = entities[1] @@ -104,6 +111,11 @@ func setupDevices( model.FunctionTypeElectricalConnectionPermittedValueSetListData, }, }, + {model.FeatureTypeTypeMeasurement, + []model.FunctionType{ + model.FunctionTypeMeasurementDescriptionListData, + }, + }, {model.FeatureTypeTypeLoadControl, []model.FunctionType{ model.FunctionTypeLoadControlLimitDescriptionListData, diff --git a/usecases/cem/oscev/public.go b/usecases/cem/oscev/public.go index 34cd7ff4..5c903bbf 100644 --- a/usecases/cem/oscev/public.go +++ b/usecases/cem/oscev/public.go @@ -25,7 +25,23 @@ func (e *OSCEV) CurrentLimits(entity spineapi.EntityRemoteInterface) ([]float64, return nil, nil, nil, err } - return ec.GetPhaseCurrentLimits() + meas, err := client.NewMeasurement(e.LocalEntity, entity) + if err != nil { + return nil, nil, nil, err + } + + filter := model.MeasurementDescriptionDataType{ + MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent), + CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), + Unit: util.Ptr(model.UnitOfMeasurementTypeA), + ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent), + } + measDesc, err := meas.GetDescriptionsForFilter(filter) + if err != nil { + return nil, nil, nil, err + } + + return ec.GetPhaseCurrentLimits(measDesc) } // return the current loadcontrol recommendation limits diff --git a/usecases/cem/oscev/public_test.go b/usecases/cem/oscev/public_test.go index 6ba0de40..187c425b 100644 --- a/usecases/cem/oscev/public_test.go +++ b/usecases/cem/oscev/public_test.go @@ -2,6 +2,8 @@ package oscev import ( ucapi "github.com/enbility/eebus-go/usecases/api" + "github.com/enbility/spine-go/model" + "github.com/enbility/spine-go/util" "github.com/stretchr/testify/assert" ) @@ -14,6 +16,26 @@ func (s *CemOSCEVSuite) Test_Public() { _, _, _, err = s.sut.CurrentLimits(s.evEntity) assert.NotNil(s.T(), err) + meas := s.evEntity.FeatureOfTypeAndRole(model.FeatureTypeTypeMeasurement, model.RoleTypeServer) + assert.NotNil(s.T(), meas) + + mData := &model.MeasurementDescriptionListDataType{ + MeasurementDescriptionData: []model.MeasurementDescriptionDataType{ + { + MeasurementId: util.Ptr(model.MeasurementIdType(0)), + MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent), + CommodityType: util.Ptr(model.CommodityTypeTypeElectricity), + Unit: util.Ptr(model.UnitOfMeasurementTypeA), + ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent), + }, + }, + } + errT := meas.UpdateData(model.FunctionTypeMeasurementDescriptionListData, mData, nil, nil) + assert.Nil(s.T(), errT) + + _, _, _, err = s.sut.CurrentLimits(s.evEntity) + assert.NotNil(s.T(), err) + _, err = s.sut.LoadControlLimits(s.mockRemoteEntity) assert.NotNil(s.T(), err) diff --git a/usecases/cem/oscev/testhelper_test.go b/usecases/cem/oscev/testhelper_test.go index 6d44235a..13978e7c 100644 --- a/usecases/cem/oscev/testhelper_test.go +++ b/usecases/cem/oscev/testhelper_test.go @@ -73,6 +73,13 @@ func (s *CemOSCEVSuite) BeforeTest(suiteName, testName string) { s.sut.AddFeatures() s.sut.AddUseCase() + var clientFeatures = []model.FeatureTypeType{ + model.FeatureTypeTypeMeasurement, + } + for _, feature := range clientFeatures { + _ = localEntity.GetOrAddFeature(feature, model.RoleTypeClient) + } + var entities []spineapi.EntityRemoteInterface s.remoteDevice, entities = setupDevices(s.service, s.T()) @@ -106,6 +113,12 @@ func setupDevices( model.FunctionTypeElectricalConnectionPermittedValueSetListData, }, }, + {model.FeatureTypeTypeMeasurement, + model.RoleTypeServer, + []model.FunctionType{ + model.FunctionTypeMeasurementDescriptionListData, + }, + }, {model.FeatureTypeTypeLoadControl, model.RoleTypeServer, []model.FunctionType{