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

Add actor based use cases #81

Merged
merged 22 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
6 changes: 3 additions & 3 deletions .github/workflows/default.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,15 @@ jobs:
uses: golangci/golangci-lint-action@master
with:
version: latest
skip-pkg-cache: true
skip-build-cache: true
skip-cache: true
skip-save-cache: true
args: --timeout=3m --issues-exit-code=0 ./...

- name: Test
run: go test -race -v -coverprofile=coverage_temp.out -covermode=atomic ./...

- name: Remove mocks and cmd from coverage
run: grep -v -e "/eebus-go/mocks/" -e "/eebus-go/cmd/" coverage_temp.out > coverage.out
run: grep -v -e "/eebus-go/mocks/" -e "/eebus-go/usecases/mocks/" -e "/eebus-go/cmd/" coverage_temp.out > coverage.out

- name: Send coverage
uses: coverallsapp/github-action@v2
Expand Down
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,10 @@ The supported functionality contains:
## Packages

- `api`: global API interface definitions and eebus service configuration
- `features`: provides feature helpers with the local SPINE feature having the client role and the remote SPINE feature being the server for easy access to commonly used functions
- `features/client`: provides feature helpers with the local SPINE feature having the client role and the remote SPINE feature being the server for easy access to commonly used functions
- `features/server`: provides feature helpers with the local SPINE feature having the server role for easy access to commonly used functions
- `service`: central package which provides access to SHIP and SPINE. Use this to create the EEBUS service, its configuration and connect to remote EEBUS services
- `util`: package with various useful helper functions
- `usecases`: containing actor and use case based implementations with use case scenario based APIs and events

## Usage

Expand Down
3 changes: 3 additions & 0 deletions api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ type ServiceInterface interface {
// shutdown the service
Shutdown()

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

// set logging interface
SetLogging(logger logging.LoggingInterface)

Expand Down
2 changes: 2 additions & 0 deletions api/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,5 @@ var ErrOperationOnFunctionNotSupported = errors.New("operation is not supported
var ErrMissingData = errors.New("missing data")

var ErrDeviceDisconnected = errors.New("device is disconnected")

var ErrNoCompatibleEntity = errors.New("no compatible entity")
4 changes: 4 additions & 0 deletions api/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package api

// type for cem and usecase specfic event names
type EventType string
51 changes: 51 additions & 0 deletions api/usecases.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package api

import (
spineapi "github.com/enbility/spine-go/api"
)

// Entity event callback
//
// Used by Use Case implementations
type EntityEventCallback func(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event EventType)

type UseCaseBaseInterface interface {
// add the use case
AddUseCase()

// update availability of the use case
UpdateUseCaseAvailability(available bool)

// check if the entity is compatible with the use case
IsCompatibleEntity(entity spineapi.EntityRemoteInterface) bool
}

// Implemented by each Use Case
type UseCaseInterface interface {
UseCaseBaseInterface

// add the features
AddFeatures()

// returns if the entity supports the usecase
//
// possible errors:
// - ErrDataNotAvailable if that information is not (yet) available
// - and others
IsUseCaseSupported(remoteEntity spineapi.EntityRemoteInterface) (bool, error)
}

type ManufacturerData struct {
DeviceName string `json:"deviceName,omitempty"`
DeviceCode string `json:"deviceCode,omitempty"`
SerialNumber string `json:"serialNumber,omitempty"`
SoftwareRevision string `json:"softwareRevision,omitempty"`
HardwareRevision string `json:"hardwareRevision,omitempty"`
VendorName string `json:"vendorName,omitempty"`
VendorCode string `json:"vendorCode,omitempty"`
BrandName string `json:"brandName,omitempty"`
PowerSource string `json:"powerSource,omitempty"`
ManufacturerNodeIdentification string `json:"manufacturerNodeIdentification,omitempty"`
ManufacturerLabel string `json:"manufacturerLabel,omitempty"`
ManufacturerDescription string `json:"manufacturerDescription,omitempty"`
}
5 changes: 5 additions & 0 deletions cmd/evse/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

"github.com/enbility/eebus-go/api"
"github.com/enbility/eebus-go/service"
"github.com/enbility/eebus-go/usecases/cs/lpc"
shipapi "github.com/enbility/ship-go/api"
"github.com/enbility/ship-go/cert"
"github.com/enbility/spine-go/model"
Expand Down Expand Up @@ -82,6 +83,10 @@ func (h *evse) run() {
return
}

localEntity := h.myService.LocalDevice().EntityForType(model.EntityTypeTypeEVSE)
uclpc := lpc.NewCsLPC(localEntity, nil)
h.myService.AddUseCase(uclpc)

if len(remoteSki) == 0 {
os.Exit(0)
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/hems/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (

"github.com/enbility/eebus-go/api"
"github.com/enbility/eebus-go/service"
"github.com/enbility/eebus-go/usecases/eg/lpc"
shipapi "github.com/enbility/ship-go/api"
"github.com/enbility/ship-go/cert"
"github.com/enbility/spine-go/model"
Expand Down Expand Up @@ -82,6 +83,10 @@ func (h *hems) run() {
return
}

localEntity := h.myService.LocalDevice().EntityForType(model.EntityTypeTypeCEM)
uclpc := lpc.NewEgLPC(localEntity, nil)
h.myService.AddUseCase(uclpc)

if len(remoteSki) == 0 {
os.Exit(0)
}
Expand Down
4 changes: 4 additions & 0 deletions features/client/deviceclassification_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ func (s *DeviceClassificationSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.deviceClassification, err = features.NewDeviceClassification(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.deviceClassification)

s.deviceClassification, err = features.NewDeviceClassification(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.deviceClassification)
Expand Down
4 changes: 4 additions & 0 deletions features/client/deviceconfiguration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,10 @@ func (s *DeviceConfigurationSuite) BeforeTest(suiteName, testName string) {
mockRemoteFeature.EXPECT().DataCopy(mock.Anything).Return(mock.Anything).Maybe()

var err error
s.deviceConfiguration, err = features.NewDeviceConfiguration(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.deviceConfiguration)

s.deviceConfiguration, err = features.NewDeviceConfiguration(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.deviceConfiguration)
Expand Down
4 changes: 4 additions & 0 deletions features/client/devicediagnosis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ func (s *DeviceDiagnosisSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.deviceDiagnosis, err = features.NewDeviceDiagnosis(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.deviceDiagnosis)

s.deviceDiagnosis, err = features.NewDeviceDiagnosis(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.deviceDiagnosis)
Expand Down
4 changes: 4 additions & 0 deletions features/client/electricalconnection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func (s *ElectricalConnectionSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.electricalConnection, err = features.NewElectricalConnection(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.electricalConnection)

s.electricalConnection, err = features.NewElectricalConnection(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.electricalConnection)
Expand Down
4 changes: 4 additions & 0 deletions features/client/feature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ func (s *FeatureSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.testFeature, err = features.NewFeature(model.FeatureTypeTypeAlarm, s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.testFeature)

s.testFeature, err = features.NewFeature(model.FeatureTypeTypeAlarm, s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.testFeature)
Expand Down
4 changes: 4 additions & 0 deletions features/client/identification_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ func (s *IdentificationSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.identification, err = features.NewIdentification(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.identification)

s.identification, err = features.NewIdentification(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.identification)
Expand Down
4 changes: 4 additions & 0 deletions features/client/incentivetable_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func (s *IncentiveTableSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.incentiveTable, err = features.NewIncentiveTable(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.incentiveTable)

s.incentiveTable, err = features.NewIncentiveTable(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.incentiveTable)
Expand Down
4 changes: 4 additions & 0 deletions features/client/loadcontrol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func (s *LoadControlSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.loadControl, err = features.NewLoadControl(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.loadControl)

s.loadControl, err = features.NewLoadControl(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.loadControl)
Expand Down
4 changes: 4 additions & 0 deletions features/client/measurement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,10 @@ func (s *MeasurementSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.measurement, err = features.NewMeasurement(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.measurement)

s.measurement, err = features.NewMeasurement(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.measurement)
Expand Down
4 changes: 4 additions & 0 deletions features/client/smartenergymanagementps_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ func (s *SmartEnergyManagementPsSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.smartenergymgmtps, err = features.NewSmartEnergyManagementPs(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.smartenergymgmtps)

s.smartenergymgmtps, err = features.NewSmartEnergyManagementPs(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.smartenergymgmtps)
Expand Down
4 changes: 4 additions & 0 deletions features/client/timeseries_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ func (s *TimeSeriesSuite) BeforeTest(suiteName, testName string) {
)

var err error
s.timeSeries, err = features.NewTimeSeries(s.localEntity, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.timeSeries)

s.timeSeries, err = features.NewTimeSeries(s.localEntity, s.remoteEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.timeSeries)
Expand Down
6 changes: 2 additions & 4 deletions features/internal/electricalconnection.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,13 +45,11 @@ func (e *ElectricalConnectionCommon) CheckEventPayloadDataForFilter(payloadData
if err != nil {
return false
}
for _, desc := range descs {
if desc.ParameterId == nil {
continue
}

for _, desc := range descs {
for _, item := range data.ElectricalConnectionPermittedValueSetData {
if item.ParameterId != nil &&
desc.ParameterId != nil &&
*item.ParameterId == *desc.ParameterId &&
len(item.PermittedValueSet) != 0 {
return true
Expand Down
3 changes: 3 additions & 0 deletions features/internal/electricalconnection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -807,6 +807,9 @@ func (s *ElectricalConnectionSuite) Test_EVCurrentLimits() {
func (s *ElectricalConnectionSuite) addDescription() {
fData := &model.ElectricalConnectionDescriptionListDataType{
ElectricalConnectionDescriptionData: []model.ElectricalConnectionDescriptionDataType{
{
PowerSupplyType: util.Ptr(model.ElectricalConnectionVoltageTypeTypeDc),
},
{
ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)),
PowerSupplyType: util.Ptr(model.ElectricalConnectionVoltageTypeTypeAc),
Expand Down
3 changes: 2 additions & 1 deletion features/internal/helper.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ func searchFilterInItem[T any](item T, filter T) bool {
continue
}

if !filterField.IsNil() && !itemField.IsNil() && filterField.Elem().Interface() != itemField.Elem().Interface() {
if (!filterField.IsNil() && !itemField.IsNil() && filterField.Elem().Interface() != itemField.Elem().Interface()) ||
(!filterField.IsNil() && itemField.IsNil()) {
match = false
break
}
Expand Down
5 changes: 1 addition & 4 deletions features/internal/loadcontrol.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,12 +42,9 @@ func (l *LoadControlCommon) CheckEventPayloadDataForFilter(payloadData any, filt

descs, _ := l.GetLimitDescriptionsForFilter(filterData)
for _, desc := range descs {
if desc.LimitId == nil {
continue
}

for _, item := range data.LoadControlLimitData {
if item.LimitId != nil &&
desc.LimitId != nil &&
*item.LimitId == *desc.LimitId &&
item.Value != nil {
return true
Expand Down
3 changes: 3 additions & 0 deletions features/server/deviceconfiguration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func (s *DeviceConfigurationSuite) BeforeTest(suiteName, testName string) {
s.remoteEntity = entities[1]

var err error
s.sut, err = server.NewDeviceConfiguration(nil)
assert.NotNil(s.T(), err)

s.sut, err = server.NewDeviceConfiguration(s.localEntity)
assert.Nil(s.T(), err)
}
Expand Down
3 changes: 3 additions & 0 deletions features/server/devicediagnosis_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func (s *DeviceDiagnosisSuite) BeforeTest(suiteName, testName string) {
s.remoteEntity = entities[1]

var err error
s.sut, err = server.NewDeviceDiagnosis(nil)
assert.NotNil(s.T(), err)

s.sut, err = server.NewDeviceDiagnosis(s.localEntity)
assert.Nil(s.T(), err)
}
Expand Down
3 changes: 3 additions & 0 deletions features/server/electricalconnection_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func (s *ElectricalConnectionSuite) BeforeTest(suiteName, testName string) {
s.remoteEntity = entities[1]

var err error
s.sut, err = server.NewElectricalConnection(nil)
assert.NotNil(s.T(), err)

s.sut, err = server.NewElectricalConnection(s.localEntity)
assert.Nil(s.T(), err)
}
Expand Down
4 changes: 4 additions & 0 deletions features/server/feature_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,10 @@ func (s *FeatureSuite) BeforeTest(suiteName, testName string) {
s.remoteEntity = entities[1]

var err error
s.testFeature, err = features.NewFeature(model.FeatureTypeTypeLoadControl, nil)
assert.NotNil(s.T(), err)
assert.Nil(s.T(), s.testFeature)

s.testFeature, err = features.NewFeature(model.FeatureTypeTypeLoadControl, s.localEntity)
assert.Nil(s.T(), err)
assert.NotNil(s.T(), s.testFeature)
Expand Down
3 changes: 3 additions & 0 deletions features/server/loadcontrol_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func (s *LoadControlSuite) BeforeTest(suiteName, testName string) {
s.remoteEntity = entities[1]

var err error
s.sut, err = server.NewLoadControl(nil)
assert.NotNil(s.T(), err)

s.sut, err = server.NewLoadControl(s.localEntity)
assert.Nil(s.T(), err)
}
Expand Down
6 changes: 4 additions & 2 deletions features/server/measurement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ func (s *MeasurementSuite) BeforeTest(suiteName, testName string) {
s.remoteEntity = entities[1]

var err error
s.sut, err = server.NewMeasurement(nil)
assert.NotNil(s.T(), err)

s.sut, err = server.NewMeasurement(s.localEntity)
assert.Nil(s.T(), err)
}
Expand Down Expand Up @@ -131,8 +134,7 @@ func (s *MeasurementSuite) Test_GetDescriptionsForFilter() {

data, err = s.sut.GetDescriptionsForFilter(filter)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 1, len(data))
assert.NotNil(s.T(), data[0].MeasurementId)
assert.Equal(s.T(), 0, len(data))

filter = model.MeasurementDescriptionDataType{
MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent),
Expand Down
Loading