Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement the MPC use case for Monitored Units #108

Open
wants to merge 19 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
d98505c
Implement MPC usecase for the MonitoredUnit actor type
nils-prommersberger Aug 5, 2024
2828ede
Add and use allEntityTypesValid boolean instead of nil validEntityTypes
nils-prommersberger Oct 14, 2024
024d8be
Update MPC to allow for updating multiple data points in one step
nils-prommersberger Oct 11, 2024
1192090
Make the mpc configurable. And support option stuff.
nils-prommersberger Oct 15, 2024
1cd1b6b
Fix comments and formatting mentioned in review
sthelen-enqs Nov 4, 2024
5f52d28
Only add scenarios when they're supported
sthelen-enqs Nov 4, 2024
014519d
refactor the addFeatures method of the mpc
nils-prommersberger Nov 20, 2024
373a3f7
Add test for the mpc-power-config PhaseConnection-function
nils-prommersberger Nov 20, 2024
86e2b8c
Ignore case for the SupportPhases function of the power config.
nils-prommersberger Nov 20, 2024
22f7190
Add more tests with mocks
nils-prommersberger Nov 20, 2024
cd4d9df
Remove panic statements with an additional wrapper struct.
nils-prommersberger Nov 20, 2024
14c29df
little fixes
nils-prommersberger Nov 22, 2024
b3e1c56
Test if the client-filters work with the data set by the server.
nils-prommersberger Nov 22, 2024
f789ffe
Let the AddFeatures method return an error
nils-prommersberger Nov 22, 2024
12654c1
Add a function in the electrical connection to get or add a Electrica…
nils-prommersberger Nov 27, 2024
f6c0bd8
Update mocks and fix service_test
sthelen-enqs Nov 29, 2024
541ba0a
Check AddFeatures return values in tests
sthelen-enqs Nov 29, 2024
05a6b42
Increase test coverage
sthelen-enqs Nov 29, 2024
6363fd7
Address comments during code review
sthelen-enqs Nov 29, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ type ServiceInterface interface {
IsRunning() bool

// add a use case to the service
AddUseCase(useCase UseCaseInterface)
AddUseCase(useCase UseCaseInterface) error

// set logging interface
SetLogging(logger logging.LoggingInterface)
Expand Down
13 changes: 11 additions & 2 deletions api/usecases.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,15 @@ type UseCaseBaseInterface interface {
type UseCaseInterface interface {
UseCaseBaseInterface

// add the features
AddFeatures()
// add the features described by the Use Case
//
// returns an error if any Feature could not be added
// - errors should not occur during normal usage of eebus-go, and should
// generally be considered fatal implementation errors
// - if an error occurs while adding features to a new Entity, that Entity
// will be in an incomplete state and should not be added to the service
//
// No cleanup occurs on error, some features may end up partially
// configured and unused
AddFeatures() error
}
10 changes: 8 additions & 2 deletions examples/ced/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,12 +99,18 @@ func (h *controlbox) run() {

localEntity := h.myService.LocalDevice().EntityForType(model.EntityTypeTypeGridGuard)
h.uclpc = lpc.NewLPC(localEntity, h.OnLPCEvent)
h.myService.AddUseCase(h.uclpc)
err = h.myService.AddUseCase(h.uclpc)
if err != nil {
log.Fatal(err)
}
// h.uclpp = lpp.NewLPP(localEntity, h.OnLPPEvent)
// h.myService.AddUseCase(h.uclpp)

h.ucmpc = mpc.NewMPC(localEntity, h.OnMPCEvent)
h.myService.AddUseCase(h.ucmpc)
err = h.myService.AddUseCase(h.ucmpc)
if err != nil {
log.Fatal(err)
}

if len(remoteSki) == 0 {
os.Exit(0)
Expand Down
10 changes: 8 additions & 2 deletions examples/controlbox/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,10 +95,16 @@ func (h *controlbox) run() {

localEntity := h.myService.LocalDevice().EntityForType(model.EntityTypeTypeGridGuard)
h.uclpc = lpc.NewLPC(localEntity, h.OnLPCEvent)
h.myService.AddUseCase(h.uclpc)
err = h.myService.AddUseCase(h.uclpc)
if err != nil {
log.Fatal(err)
}

h.uclpp = lpp.NewLPP(localEntity, h.OnLPPEvent)
h.myService.AddUseCase(h.uclpp)
err = h.myService.AddUseCase(h.uclpp)
if err != nil {
log.Fatal(err)
}

if len(remoteSki) == 0 {
os.Exit(0)
Expand Down
5 changes: 4 additions & 1 deletion examples/evse/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ func (h *evse) run() {

localEntity := h.myService.LocalDevice().EntityForType(model.EntityTypeTypeEVSE)
h.uclpc = lpc.NewLPC(localEntity, h.OnLPCEvent)
h.myService.AddUseCase(h.uclpc)
err = h.myService.AddUseCase(h.uclpc)
if err != nil {
log.Fatal(err)
}

// Initialize local server data
_ = h.uclpc.SetConsumptionNominalMax(32000)
Expand Down
41 changes: 34 additions & 7 deletions examples/hems/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,19 +102,46 @@ func (h *hems) run() {

localEntity := h.myService.LocalDevice().EntityForType(model.EntityTypeTypeCEM)
h.uccslpc = cslpc.NewLPC(localEntity, h.OnLPCEvent)
h.myService.AddUseCase(h.uccslpc)
err = h.myService.AddUseCase(h.uccslpc)
if err != nil {
log.Fatal(err)
}

h.uccslpp = cslpp.NewLPP(localEntity, h.OnLPPEvent)
h.myService.AddUseCase(h.uccslpp)
err = h.myService.AddUseCase(h.uccslpp)
if err != nil {
log.Fatal(err)
}

h.uceglpc = eglpc.NewLPC(localEntity, nil)
h.myService.AddUseCase(h.uceglpc)
err = h.myService.AddUseCase(h.uceglpc)
if err != nil {
log.Fatal(err)
}

h.uceglpp = eglpp.NewLPP(localEntity, nil)
h.myService.AddUseCase(h.uceglpp)
err = h.myService.AddUseCase(h.uceglpp)
if err != nil {
log.Fatal(err)
}

h.ucmamgcp = mgcp.NewMGCP(localEntity, h.OnMGCPEvent)
h.myService.AddUseCase(h.ucmamgcp)
err = h.myService.AddUseCase(h.ucmamgcp)
if err != nil {
log.Fatal(err)
}

h.uccemvabd = vabd.NewVABD(localEntity, h.OnVABDEvent)
h.myService.AddUseCase(h.uccemvabd)
err = h.myService.AddUseCase(h.uccemvabd)
if err != nil {
log.Fatal(err)
}

h.uccemvapd = vapd.NewVAPD(localEntity, h.OnVAPDEvent)
h.myService.AddUseCase(h.uccemvapd)
err = h.myService.AddUseCase(h.uccemvapd)
if err != nil {
log.Fatal(err)
}

// Initialize local server data
_ = h.uccslpc.SetConsumptionNominalMax(32000)
Expand Down
6 changes: 5 additions & 1 deletion examples/remote/ucs.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"context"
"fmt"
"log"

"github.com/enbility/eebus-go/api"
spineapi "github.com/enbility/spine-go/api"
Expand Down Expand Up @@ -31,7 +32,10 @@ func (r *Remote) RegisterUseCase(entityType model.EntityTypeType, usecaseId stri
) {
r.PropagateEvent(identifier, ski, device, entity, event)
})
r.service.AddUseCase(uc)
err := r.service.AddUseCase(uc)
if err != nil {
log.Fatal(err)
}

return r.registerStaticReceiverProxy(usecaseId, uc)
}
Expand Down
42 changes: 42 additions & 0 deletions features/server/electricalconnection.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,48 @@ func NewElectricalConnection(localEntity spineapi.EntityLocalInterface) (*Electr
return ec, nil
}

func (e *ElectricalConnection) GetOrAddIdForDescription(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add comments for this function to understand its usage

electricalConnectionDescription model.ElectricalConnectionDescriptionDataType,
) (*model.ElectricalConnectionIdType, error) {
electricalConnectionId := (*model.ElectricalConnectionIdType)(nil)
highestExistingElectricalConnectionId := model.ElectricalConnectionIdType(0)

descriptionData := e.featureLocal.DataCopy(model.FunctionTypeElectricalConnectionDescriptionListData).(*model.ElectricalConnectionDescriptionListDataType)

if descriptionData != nil && descriptionData.ElectricalConnectionDescriptionData != nil {
for _, description := range descriptionData.ElectricalConnectionDescriptionData {
if description.ElectricalConnectionId != nil &&
description.PowerSupplyType == electricalConnectionDescription.PowerSupplyType &&
description.AcConnectedPhases == electricalConnectionDescription.AcConnectedPhases &&
description.AcRmsPeriodDuration == electricalConnectionDescription.AcRmsPeriodDuration &&
description.PositiveEnergyDirection == electricalConnectionDescription.PositiveEnergyDirection &&
description.ScopeType == electricalConnectionDescription.ScopeType &&
description.Label == electricalConnectionDescription.Label &&
description.Description == electricalConnectionDescription.Description {
electricalConnectionId = description.ElectricalConnectionId
break
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about returning here directly? That would remove the need for the if statement in line 62

} else if description.ElectricalConnectionId != nil {
if *description.ElectricalConnectionId > highestExistingElectricalConnectionId {
highestExistingElectricalConnectionId = *description.ElectricalConnectionId
}
}
}
}

if electricalConnectionId == nil {
electricalConnectionId = util.Ptr(highestExistingElectricalConnectionId + 1)
description := electricalConnectionDescription
description.ElectricalConnectionId = electricalConnectionId
if errType := e.featureLocal.UpdateData(model.FunctionTypeElectricalConnectionDescriptionListData, &model.ElectricalConnectionDescriptionListDataType{
ElectricalConnectionDescriptionData: []model.ElectricalConnectionDescriptionDataType{description},
}, model.NewFilterTypePartial(), nil); errType != nil {
return nil, errors.New("could not add description data")
}
}

return electricalConnectionId, nil
}

// Add a new description data set
//
// NOTE: the electricalConnectionId has to be provided
Expand Down
34 changes: 34 additions & 0 deletions features/server/electricalconnection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,40 @@ func (s *ElectricalConnectionSuite) Test_Description() {
assert.NotNil(s.T(), data)
}

func (s *ElectricalConnectionSuite) Test_GetOrAddIdForDescription() {
filter := model.ElectricalConnectionDescriptionDataType{}

data, err := s.sut.GetDescriptionsForFilter(filter)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), data)

desc1 := model.ElectricalConnectionDescriptionDataType{
PowerSupplyType: util.Ptr(model.ElectricalConnectionVoltageTypeTypeDc),
ScopeType: util.Ptr(model.ScopeTypeTypeACPowerTotal),
}

eConnectionId, err := s.sut.GetOrAddIdForDescription(desc1)
assert.Nil(s.T(), err)
assert.Equal(s.T(), model.ElectricalConnectionIdType(1), *eConnectionId)

eConnectionId, err = s.sut.GetOrAddIdForDescription(desc1)
assert.Nil(s.T(), err)
assert.Equal(s.T(), model.ElectricalConnectionIdType(1), *eConnectionId)

desc2 := model.ElectricalConnectionDescriptionDataType{
PowerSupplyType: util.Ptr(model.ElectricalConnectionVoltageTypeTypeAc),
ScopeType: util.Ptr(model.ScopeTypeTypeACPowerTotal),
}

eConnectionId2, err := s.sut.GetOrAddIdForDescription(desc2)
assert.Nil(s.T(), err)
assert.Equal(s.T(), model.ElectricalConnectionIdType(2), *eConnectionId2)

eConnectionId, err = s.sut.GetOrAddIdForDescription(desc1)
assert.Nil(s.T(), err)
assert.Equal(s.T(), model.ElectricalConnectionIdType(1), *eConnectionId)
}

func (s *ElectricalConnectionSuite) Test_ParameterDescription() {
filter := model.ElectricalConnectionParameterDescriptionDataType{}

Expand Down
2 changes: 1 addition & 1 deletion mocks/DeviceClassificationClientInterface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mocks/DeviceClassificationCommonInterface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion mocks/DeviceClassificationServerInterface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions mocks/DeviceConfigurationClientInterface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 8 additions & 8 deletions mocks/DeviceConfigurationCommonInterface.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading