Skip to content

Commit fed478a

Browse files
committed
Add missing MPC and MGPC cases
1 parent bf4dad9 commit fed478a

File tree

4 files changed

+253
-9
lines changed

4 files changed

+253
-9
lines changed

usecases/ma/mgcp/public.go

Lines changed: 58 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,14 @@ import (
1515
// return the current power limitation factor
1616
//
1717
// possible errors:
18-
// - ErrDataNotAvailable if no such limit is (yet) available
18+
// - ErrDataNotAvailable if no such value is (yet) available
19+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
1920
// - and others
2021
func (e *MGCP) PowerLimitationFactor(entity spineapi.EntityRemoteInterface) (float64, error) {
2122
if !e.IsCompatibleEntityType(entity) {
2223
return 0, api.ErrNoCompatibleEntity
2324
}
2425

25-
measurement, err := client.NewMeasurement(e.LocalEntity, entity)
26-
if err != nil || measurement == nil {
27-
return 0, err
28-
}
29-
3026
keyname := model.DeviceConfigurationKeyNameTypePvCurtailmentLimitFactor
3127

3228
deviceConfiguration, err := client.NewDeviceConfiguration(e.LocalEntity, entity)
@@ -58,6 +54,11 @@ func (e *MGCP) PowerLimitationFactor(entity spineapi.EntityRemoteInterface) (flo
5854
//
5955
// - positive values are used for consumption
6056
// - negative values are used for production
57+
//
58+
// possible errors:
59+
// - ErrDataNotAvailable if no such value is (yet) available
60+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
61+
// - and others
6162
func (e *MGCP) Power(entity spineapi.EntityRemoteInterface) (float64, error) {
6263
if !e.IsCompatibleEntityType(entity) {
6364
return 0, api.ErrNoCompatibleEntity
@@ -69,7 +70,11 @@ func (e *MGCP) Power(entity spineapi.EntityRemoteInterface) (float64, error) {
6970
ScopeType: util.Ptr(model.ScopeTypeTypeACPowerTotal),
7071
}
7172
data, err := internal.MeasurementPhaseSpecificDataForFilter(e.LocalEntity, entity, filter, model.EnergyDirectionTypeConsume, nil)
72-
if err != nil || len(data) != 1 {
73+
if err != nil {
74+
return 0, err
75+
}
76+
77+
if len(data) != 1 {
7378
return 0, api.ErrDataNotAvailable
7479
}
7580

@@ -81,6 +86,11 @@ func (e *MGCP) Power(entity spineapi.EntityRemoteInterface) (float64, error) {
8186
// return the total feed in energy at the grid connection point
8287
//
8388
// - negative values are used for production
89+
//
90+
// possible errors:
91+
// - ErrDataNotAvailable if no such value is (yet) available
92+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
93+
// - and others
8494
func (e *MGCP) EnergyFeedIn(entity spineapi.EntityRemoteInterface) (float64, error) {
8595
if !e.IsCompatibleEntityType(entity) {
8696
return 0, api.ErrNoCompatibleEntity
@@ -100,6 +110,13 @@ func (e *MGCP) EnergyFeedIn(entity spineapi.EntityRemoteInterface) (float64, err
100110
if err != nil || len(result) == 0 || result[0].Value == nil {
101111
return 0, api.ErrDataNotAvailable
102112
}
113+
114+
// if the value state is set and not normal, the value is not valid and should be ignored
115+
// therefore we return an error
116+
if result[0].ValueState != nil && *result[0].ValueState != model.MeasurementValueStateTypeNormal {
117+
return 0, api.ErrDataInvalid
118+
}
119+
103120
return result[0].Value.GetValue(), nil
104121
}
105122

@@ -108,6 +125,11 @@ func (e *MGCP) EnergyFeedIn(entity spineapi.EntityRemoteInterface) (float64, err
108125
// return the total consumption energy at the grid connection point
109126
//
110127
// - positive values are used for consumption
128+
//
129+
// possible errors:
130+
// - ErrDataNotAvailable if no such value is (yet) available
131+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
132+
// - and others
111133
func (e *MGCP) EnergyConsumed(entity spineapi.EntityRemoteInterface) (float64, error) {
112134
if !e.IsCompatibleEntityType(entity) {
113135
return 0, api.ErrNoCompatibleEntity
@@ -127,6 +149,13 @@ func (e *MGCP) EnergyConsumed(entity spineapi.EntityRemoteInterface) (float64, e
127149
if err != nil || len(result) == 0 || result[0].Value == nil {
128150
return 0, api.ErrDataNotAvailable
129151
}
152+
153+
// if the value state is set and not normal, the value is not valid and should be ignored
154+
// therefore we return an error
155+
if result[0].ValueState != nil && *result[0].ValueState != model.MeasurementValueStateTypeNormal {
156+
return 0, api.ErrDataInvalid
157+
}
158+
130159
return result[0].Value.GetValue(), nil
131160
}
132161

@@ -136,6 +165,11 @@ func (e *MGCP) EnergyConsumed(entity spineapi.EntityRemoteInterface) (float64, e
136165
//
137166
// - positive values are used for consumption
138167
// - negative values are used for production
168+
//
169+
// possible errors:
170+
// - ErrDataNotAvailable if no such value is (yet) available
171+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
172+
// - and others
139173
func (e *MGCP) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) {
140174
if !e.IsCompatibleEntityType(entity) {
141175
return nil, api.ErrNoCompatibleEntity
@@ -152,6 +186,11 @@ func (e *MGCP) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64
152186
// Scenario 6
153187

154188
// return the voltage phase details at the grid connection point
189+
//
190+
// possible errors:
191+
// - ErrDataNotAvailable if no such value is (yet) available
192+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
193+
// - and others
155194
func (e *MGCP) VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) {
156195
if !e.IsCompatibleEntityType(entity) {
157196
return nil, api.ErrNoCompatibleEntity
@@ -168,6 +207,11 @@ func (e *MGCP) VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64
168207
// Scenario 7
169208

170209
// return frequency at the grid connection point
210+
//
211+
// possible errors:
212+
// - ErrDataNotAvailable if no such value is (yet) available
213+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
214+
// - and others
171215
func (e *MGCP) Frequency(entity spineapi.EntityRemoteInterface) (float64, error) {
172216
if !e.IsCompatibleEntityType(entity) {
173217
return 0, api.ErrNoCompatibleEntity
@@ -187,5 +231,12 @@ func (e *MGCP) Frequency(entity spineapi.EntityRemoteInterface) (float64, error)
187231
if err != nil || len(result) == 0 || result[0].Value == nil {
188232
return 0, api.ErrDataNotAvailable
189233
}
234+
235+
// if the value state is set and not normal, the value is not valid and should be ignored
236+
// therefore we return an error
237+
if result[0].ValueState != nil && *result[0].ValueState != model.MeasurementValueStateTypeNormal {
238+
return 0, api.ErrDataInvalid
239+
}
240+
190241
return result[0].Value.GetValue(), nil
191242
}

usecases/ma/mgcp/public_test.go

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -173,6 +173,23 @@ func (s *GcpMGCPSuite) Test_EnergyFeedIn() {
173173
data, err = s.sut.EnergyFeedIn(s.smgwEntity)
174174
assert.Nil(s.T(), err)
175175
assert.Equal(s.T(), 10.0, data)
176+
177+
measData = &model.MeasurementListDataType{
178+
MeasurementData: []model.MeasurementDataType{
179+
{
180+
MeasurementId: util.Ptr(model.MeasurementIdType(0)),
181+
Value: model.NewScaledNumberType(10),
182+
ValueState: util.Ptr(model.MeasurementValueStateTypeError),
183+
},
184+
},
185+
}
186+
187+
_, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementListData, measData, nil, nil)
188+
assert.Nil(s.T(), fErr)
189+
190+
data, err = s.sut.EnergyFeedIn(s.smgwEntity)
191+
assert.NotNil(s.T(), err)
192+
assert.Equal(s.T(), 0.0, data)
176193
}
177194

178195
func (s *GcpMGCPSuite) Test_EnergyConsumed() {
@@ -218,6 +235,23 @@ func (s *GcpMGCPSuite) Test_EnergyConsumed() {
218235
data, err = s.sut.EnergyConsumed(s.smgwEntity)
219236
assert.Nil(s.T(), err)
220237
assert.Equal(s.T(), 10.0, data)
238+
239+
measData = &model.MeasurementListDataType{
240+
MeasurementData: []model.MeasurementDataType{
241+
{
242+
MeasurementId: util.Ptr(model.MeasurementIdType(0)),
243+
Value: model.NewScaledNumberType(10),
244+
ValueState: util.Ptr(model.MeasurementValueStateTypeError),
245+
},
246+
},
247+
}
248+
249+
_, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementListData, measData, nil, nil)
250+
assert.Nil(s.T(), fErr)
251+
252+
data, err = s.sut.EnergyConsumed(s.smgwEntity)
253+
assert.NotNil(s.T(), err)
254+
assert.Equal(s.T(), 0.0, data)
221255
}
222256

223257
func (s *GcpMGCPSuite) Test_CurrentPerPhase() {
@@ -461,4 +495,21 @@ func (s *GcpMGCPSuite) Test_Frequency() {
461495
data, err = s.sut.Frequency(s.smgwEntity)
462496
assert.Nil(s.T(), err)
463497
assert.Equal(s.T(), 50.0, data)
498+
499+
measData = &model.MeasurementListDataType{
500+
MeasurementData: []model.MeasurementDataType{
501+
{
502+
MeasurementId: util.Ptr(model.MeasurementIdType(0)),
503+
Value: model.NewScaledNumberType(50),
504+
ValueState: util.Ptr(model.MeasurementValueStateTypeError),
505+
},
506+
},
507+
}
508+
509+
_, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementListData, measData, nil, nil)
510+
assert.Nil(s.T(), fErr)
511+
512+
data, err = s.sut.Frequency(s.smgwEntity)
513+
assert.NotNil(s.T(), err)
514+
assert.Equal(s.T(), 0.0, data)
464515
}

usecases/ma/mpc/public.go

Lines changed: 48 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ import (
1515
// return the momentary active power consumption or production
1616
//
1717
// possible errors:
18-
// - ErrDataNotAvailable if no such limit is (yet) available
18+
// - ErrDataNotAvailable if no such value is (yet) available
19+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
1920
// - and others
2021
func (e *MPC) Power(entity spineapi.EntityRemoteInterface) (float64, error) {
2122
if !e.IsCompatibleEntityType(entity) {
@@ -34,13 +35,15 @@ func (e *MPC) Power(entity spineapi.EntityRemoteInterface) (float64, error) {
3435
if len(values) != 1 {
3536
return 0, api.ErrDataNotAvailable
3637
}
38+
3739
return values[0], nil
3840
}
3941

4042
// return the momentary active phase specific power consumption or production per phase
4143
//
4244
// possible errors:
43-
// - ErrDataNotAvailable if no such limit is (yet) available
45+
// - ErrDataNotAvailable if no such value is (yet) available
46+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
4447
// - and others
4548
func (e *MPC) PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) {
4649
if !e.IsCompatibleEntityType(entity) {
@@ -60,6 +63,11 @@ func (e *MPC) PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, e
6063
// return the total consumption energy
6164
//
6265
// - positive values are used for consumption
66+
//
67+
// possible errors:
68+
// - ErrDataNotAvailable if no such value is (yet) available
69+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
70+
// - and others
6371
func (e *MPC) EnergyConsumed(entity spineapi.EntityRemoteInterface) (float64, error) {
6472
if !e.IsCompatibleEntityType(entity) {
6573
return 0, api.ErrNoCompatibleEntity
@@ -86,12 +94,23 @@ func (e *MPC) EnergyConsumed(entity spineapi.EntityRemoteInterface) (float64, er
8694
return 0, api.ErrDataNotAvailable
8795
}
8896

97+
// if the value state is set and not normal, the value is not valid and should be ignored
98+
// therefore we return an error
99+
if values[0].ValueState != nil && *values[0].ValueState != model.MeasurementValueStateTypeNormal {
100+
return 0, api.ErrDataInvalid
101+
}
102+
89103
return value.GetValue(), nil
90104
}
91105

92106
// return the total feed in energy
93107
//
94108
// - negative values are used for production
109+
//
110+
// possible errors:
111+
// - ErrDataNotAvailable if no such value is (yet) available
112+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
113+
// - and others
95114
func (e *MPC) EnergyProduced(entity spineapi.EntityRemoteInterface) (float64, error) {
96115
if !e.IsCompatibleEntityType(entity) {
97116
return 0, api.ErrNoCompatibleEntity
@@ -118,6 +137,12 @@ func (e *MPC) EnergyProduced(entity spineapi.EntityRemoteInterface) (float64, er
118137
return 0, api.ErrDataNotAvailable
119138
}
120139

140+
// if the value state is set and not normal, the value is not valid and should be ignored
141+
// therefore we return an error
142+
if values[0].ValueState != nil && *values[0].ValueState != model.MeasurementValueStateTypeNormal {
143+
return 0, api.ErrDataInvalid
144+
}
145+
121146
return value.GetValue(), nil
122147
}
123148

@@ -127,6 +152,11 @@ func (e *MPC) EnergyProduced(entity spineapi.EntityRemoteInterface) (float64, er
127152
//
128153
// - positive values are used for consumption
129154
// - negative values are used for production
155+
//
156+
// possible errors:
157+
// - ErrDataNotAvailable if no such value is (yet) available
158+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
159+
// - and others
130160
func (e *MPC) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) {
131161
if !e.IsCompatibleEntityType(entity) {
132162
return nil, api.ErrNoCompatibleEntity
@@ -143,6 +173,11 @@ func (e *MPC) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64,
143173
// Scenario 4
144174

145175
// return the phase specific voltage details
176+
//
177+
// possible errors:
178+
// - ErrDataNotAvailable if no such value is (yet) available
179+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
180+
// - and others
146181
func (e *MPC) VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) {
147182
if !e.IsCompatibleEntityType(entity) {
148183
return nil, api.ErrNoCompatibleEntity
@@ -159,6 +194,11 @@ func (e *MPC) VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64,
159194
// Scenario 5
160195

161196
// return frequency
197+
//
198+
// possible errors:
199+
// - ErrDataNotAvailable if no such value is (yet) available
200+
// - ErrDataInvalid if the currently available data is invalid and should be ignored
201+
// - and others
162202
func (e *MPC) Frequency(entity spineapi.EntityRemoteInterface) (float64, error) {
163203
if !e.IsCompatibleEntityType(entity) {
164204
return 0, api.ErrNoCompatibleEntity
@@ -179,6 +219,12 @@ func (e *MPC) Frequency(entity spineapi.EntityRemoteInterface) (float64, error)
179219
return 0, api.ErrDataNotAvailable
180220
}
181221

222+
// if the value state is set and not normal, the value is not valid and should be ignored
223+
// therefore we return an error
224+
if data[0].ValueState != nil && *data[0].ValueState != model.MeasurementValueStateTypeNormal {
225+
return 0, api.ErrDataInvalid
226+
}
227+
182228
// take the first item
183229
value := data[0].Value
184230

0 commit comments

Comments
 (0)