Skip to content
This repository has been archived by the owner on Jun 29, 2024. It is now read-only.

Commit

Permalink
Add handling and events for device (dis-)connections
Browse files Browse the repository at this point in the history
- Updated UseCaseEventReaderInterface interface to provide the device
  • Loading branch information
DerAndereAndi committed Feb 25, 2024
1 parent 4a2ceb7 commit a5ecbc0
Show file tree
Hide file tree
Showing 33 changed files with 192 additions and 138 deletions.
2 changes: 1 addition & 1 deletion api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,5 +50,5 @@ type UseCaseInterface interface {
// implemented by the actual CEM, used by UCEvseCCInterface implementation
type UseCaseEventReaderInterface interface {
// Inform about a new usecase specific event
SpineEvent(ski string, entity spineapi.EntityRemoteInterface, event UseCaseEventType)
SpineEvent(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event UseCaseEventType)
}
8 changes: 8 additions & 0 deletions api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,14 @@ const (
type UseCaseEventType string

const (
// CEM

// Sent when a paired remote device was connected
DeviceConnected UseCaseEventType = "deviceConnected"

// Sent when a paired remote device was disconnected
DeviceDisconnected UseCaseEventType = "deviceDisconnected"

// UCCEVC

// EV provided an energy demand
Expand Down
9 changes: 8 additions & 1 deletion cem/cem.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,20 @@ type Cem struct {

Currency model.CurrencyType

reader api.UseCaseEventReaderInterface

usecases []api.UseCaseInterface
}

func NewCEM(serviceDescription *eebusapi.Configuration, serviceHandler eebusapi.ServiceReaderInterface, log logging.LoggingInterface) *Cem {
func NewCEM(
serviceDescription *eebusapi.Configuration,
serviceHandler eebusapi.ServiceReaderInterface,
reader api.UseCaseEventReaderInterface,
log logging.LoggingInterface) *Cem {
cem := &Cem{
Service: service.NewService(serviceDescription, serviceHandler),
Currency: model.CurrencyTypeEur,
reader: reader,
}

cem.Service.SetLogging(log)
Expand Down
109 changes: 37 additions & 72 deletions cem/cem_test.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
package cem

import (
"fmt"
"testing"
"time"

Expand All @@ -12,13 +11,28 @@ import (
"github.com/enbility/ship-go/cert"
"github.com/enbility/ship-go/logging"
spineapi "github.com/enbility/spine-go/api"
"github.com/enbility/spine-go/mocks"
"github.com/enbility/spine-go/model"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/suite"
)

func Test_CEM(t *testing.T) {
func TestCemSuite(t *testing.T) {
suite.Run(t, new(CemSuite))
}

type CemSuite struct {
suite.Suite

sut *Cem
mockRemoteDevice *mocks.DeviceRemoteInterface
}

func (s *CemSuite) BeforeTest(suiteName, testName string) {
s.mockRemoteDevice = mocks.NewDeviceRemoteInterface(s.T())

certificate, err := cert.CreateCertificate("Demo", "Demo", "DE", "Demo-Unit-10")
assert.Nil(t, err)
assert.Nil(s.T(), err)

configuration, err := eebusapi.NewConfiguration(
"Demo",
Expand All @@ -31,94 +45,45 @@ func Test_CEM(t *testing.T) {
certificate,
230,
time.Second*4)
assert.Nil(t, err)

demo := &DemoCem{}
cem := NewCEM(configuration, demo, demo)
assert.NotNil(t, cem)

err = cem.Setup()
assert.Nil(t, err)

ucEvseCC := ucevsecc.NewUCEVSECC(cem.Service, cem.Service.LocalService(), demo)
cem.AddUseCase(ucEvseCC)

cem.Start()
cem.Shutdown()
assert.Nil(s.T(), err)

noLogging := &logging.NoLogging{}
s.sut = NewCEM(configuration, s, s, noLogging)
assert.NotNil(s.T(), s.sut)
}
func (s *CemSuite) Test_CEM() {
err := s.sut.Setup()
assert.Nil(s.T(), err)

ucEvseCC := ucevsecc.NewUCEVSECC(s.sut.Service, s.sut.Service.LocalService(), s)
s.sut.AddUseCase(ucEvseCC)

type DemoCem struct {
s.sut.Start()
s.sut.Shutdown()
}

// UseCaseEventReaderInterface

func (d *DemoCem) SpineEvent(ski string, entity spineapi.EntityRemoteInterface, event api.UseCaseEventType) {

func (d *CemSuite) SpineEvent(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event api.UseCaseEventType) {
}

// eebusapi.ServiceReaderInterface

// report the Ship ID of a newly trusted connection
func (d *DemoCem) RemoteServiceShipIDReported(service eebusapi.ServiceInterface, ski string, shipID string) {
func (d *CemSuite) RemoteServiceShipIDReported(service eebusapi.ServiceInterface, ski string, shipID string) {
// we should associated the Ship ID with the SKI and store it
// so the next connection can start trusted
logging.Log().Info("SKI", ski, "has Ship ID:", shipID)
}

func (d *DemoCem) RemoteSKIConnected(service eebusapi.ServiceInterface, ski string) {}

func (d *DemoCem) RemoteSKIDisconnected(service eebusapi.ServiceInterface, ski string) {}

func (d *DemoCem) VisibleRemoteServicesUpdated(service eebusapi.ServiceInterface, entries []shipapi.RemoteService) {
}

func (h *DemoCem) ServiceShipIDUpdate(ski string, shipdID string) {}
func (d *CemSuite) RemoteSKIConnected(service eebusapi.ServiceInterface, ski string) {}

func (h *DemoCem) ServicePairingDetailUpdate(ski string, detail *shipapi.ConnectionStateDetail) {}
func (d *CemSuite) RemoteSKIDisconnected(service eebusapi.ServiceInterface, ski string) {}

func (h *DemoCem) AllowWaitingForTrust(ski string) bool { return true }

// Logging interface

func (d *DemoCem) log(level string, args ...interface{}) {
t := time.Now()
fmt.Printf("%s: %s %s", t.Format(time.RFC3339), level, fmt.Sprintln(args...))
func (d *CemSuite) VisibleRemoteServicesUpdated(service eebusapi.ServiceInterface, entries []shipapi.RemoteService) {
}

func (d *DemoCem) logf(level, format string, args ...interface{}) {
t := time.Now()
fmt.Printf("%s: %s %s\n", t.Format(time.RFC3339), level, fmt.Sprintf(format, args...))
}
func (h *CemSuite) ServiceShipIDUpdate(ski string, shipdID string) {}

func (d *DemoCem) Trace(args ...interface{}) {
d.log("TRACE", args...)
}
func (h *CemSuite) ServicePairingDetailUpdate(ski string, detail *shipapi.ConnectionStateDetail) {}

func (d *DemoCem) Tracef(format string, args ...interface{}) {
d.logf("TRACE", format, args...)
}

func (d *DemoCem) Debug(args ...interface{}) {
d.log("DEBUG", args...)
}

func (d *DemoCem) Debugf(format string, args ...interface{}) {
d.logf("DEBUG", format, args...)
}

func (d *DemoCem) Info(args ...interface{}) {
d.log("INFO", args...)
}

func (d *DemoCem) Infof(format string, args ...interface{}) {
d.logf("INFO", format, args...)
}

func (d *DemoCem) Error(args ...interface{}) {
d.log("ERROR", args...)
}

func (d *DemoCem) Errorf(format string, args ...interface{}) {
d.logf("ERROR", format, args...)
}
func (h *CemSuite) AllowWaitingForTrust(ski string) bool { return true }
21 changes: 21 additions & 0 deletions cem/events.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
package cem

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

// handle SPINE events
func (h *Cem) HandleEvent(payload spineapi.EventPayload) {

if util.IsDeviceConnected(payload) {
h.reader.SpineEvent(payload.Ski, payload.Device, nil, api.DeviceConnected)
return
}

if util.IsDeviceDisconnected(payload) {
h.reader.SpineEvent(payload.Ski, payload.Device, nil, api.DeviceDisconnected)
return
}
}
20 changes: 20 additions & 0 deletions cem/events_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
package cem

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

func (s *CemSuite) Test_Events() {
payload := spineapi.EventPayload{
Device: s.mockRemoteDevice,
}
s.sut.HandleEvent(payload)

payload.EventType = spineapi.EventTypeDeviceChange
payload.ChangeType = spineapi.ElementChangeRemove
s.sut.HandleEvent(payload)

payload.EventType = spineapi.EventTypeDeviceChange
payload.ChangeType = spineapi.ElementChangeRemove
s.sut.HandleEvent(payload)
}
2 changes: 1 addition & 1 deletion cmd/democem/democem.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ type DemoCem struct {
func NewDemoCem(configuration *eebusapi.Configuration) *DemoCem {
demo := &DemoCem{}

demo.cem = cem.NewCEM(configuration, demo, demo)
demo.cem = cem.NewCEM(configuration, demo, demo, demo)

return demo
}
Expand Down
2 changes: 1 addition & 1 deletion cmd/democem/eventreader.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,5 @@ import (
var _ api.UseCaseEventReaderInterface = (*DemoCem)(nil)

// Handle incomfing usecase specific event
func (h *DemoCem) SpineEvent(ski string, entity spineapi.EntityRemoteInterface, event api.UseCaseEventType) {
func (h *DemoCem) SpineEvent(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event api.UseCaseEventType) {
}
6 changes: 6 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,9 @@ require (
golang.org/x/tools v0.17.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)

// replace github.com/enbility/eebus-go => ../eebus-go

// replace github.com/enbility/ship-go => ../ship-go

// replace github.com/enbility/spine-go => ../spine-go
14 changes: 7 additions & 7 deletions uccevc/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ func (e *UCCEVC) evTimeSeriesDescriptionDataUpdate(ski string, entity spineapi.E
return
}

e.reader.SpineEvent(ski, entity, api.UCCEVCEnergyDemandProvided)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCCEVCEnergyDemandProvided)

_, err = e.TimeSlotConstraints(entity)
if err != nil {
Expand All @@ -127,18 +127,18 @@ func (e *UCCEVC) evTimeSeriesDescriptionDataUpdate(ski string, entity spineapi.E
return
}

e.reader.SpineEvent(ski, entity, api.UCCEVPowerLimitsRequested)
e.reader.SpineEvent(ski, entity, api.UCCEVCIncentivesRequested)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCCEVPowerLimitsRequested)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCCEVCIncentivesRequested)
}

// the load control limit data of an EV was updated
func (e *UCCEVC) evTimeSeriesDataUpdate(ski string, entity spineapi.EntityRemoteInterface) {
if _, err := e.ChargePlan(entity); err == nil {
e.reader.SpineEvent(ski, entity, api.UCCEVCChargePlanProvided)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCCEVCChargePlanProvided)
}

if _, err := e.ChargePlanConstraints(entity); err == nil {
e.reader.SpineEvent(ski, entity, api.UCCEVCChargePlanConstraintsProvided)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCCEVCChargePlanConstraintsProvided)
}
}

Expand All @@ -156,12 +156,12 @@ func (e *UCCEVC) evIncentiveTableDescriptionDataUpdate(ski string, entity spinea
return
}

e.reader.SpineEvent(ski, entity, api.UCCEVCIncentiveDescriptionsRequired)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCCEVCIncentiveDescriptionsRequired)
}

// the load control limit data of an EV was updated
func (e *UCCEVC) evIncentiveTableDataUpdate(ski string, entity spineapi.EntityRemoteInterface) {
e.reader.SpineEvent(ski, entity, api.UCCEVCIncentiveTableDataUpdate)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCCEVCIncentiveTableDataUpdate)
}

// check timeSeries descriptions if constraints element has updateRequired set to true
Expand Down
2 changes: 1 addition & 1 deletion uccevc/testhelper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type UCCEVCSuite struct {
evEntity spineapi.EntityRemoteInterface
}

func (s *UCCEVCSuite) SpineEvent(ski string, entity spineapi.EntityRemoteInterface, event api.UseCaseEventType) {
func (s *UCCEVCSuite) SpineEvent(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event api.UseCaseEventType) {
}

func (s *UCCEVCSuite) BeforeTest(suiteName, testName string) {
Expand Down
14 changes: 7 additions & 7 deletions ucevcc/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@ func (e *UCEVCC) evConnected(ski string, entity spineapi.EntityRemoteInterface)
}
}

e.reader.SpineEvent(ski, entity, api.UCEVCCEventConnected)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCEVCCEventConnected)
}

// an EV was disconnected
func (e *UCEVCC) evDisconnected(ski string, entity spineapi.EntityRemoteInterface) {
e.reader.SpineEvent(ski, entity, api.UCEVCCEventDisconnected)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCEVCCEventDisconnected)
}

// the configuration key description data of an EV was updated
Expand All @@ -139,12 +139,12 @@ func (e *UCEVCC) evConfigurationDataUpdate(ski string, entity spineapi.EntityRem

// Scenario 2
if _, err := evDeviceConfiguration.GetKeyValueForKeyName(model.DeviceConfigurationKeyNameTypeCommunicationsStandard, model.DeviceConfigurationKeyValueTypeTypeString); err == nil {
e.reader.SpineEvent(ski, entity, api.UCEVCCCommunicationStandardConfigurationDataUpdate)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCEVCCCommunicationStandardConfigurationDataUpdate)
}

// Scenario 3
if _, err := evDeviceConfiguration.GetKeyValueForKeyName(model.DeviceConfigurationKeyNameTypeAsymmetricChargingSupported, model.DeviceConfigurationKeyValueTypeTypeString); err == nil {
e.reader.SpineEvent(ski, entity, api.UCEVCCAsymmetricChargingConfigurationDataUpdate)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCEVCCAsymmetricChargingConfigurationDataUpdate)
}
}

Expand All @@ -162,7 +162,7 @@ func (e *UCEVCC) evIdentificationDataUpdate(ski string, entity spineapi.EntityRe
continue
}

e.reader.SpineEvent(ski, entity, api.UCEVCCIdentificationDataUpdate)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCEVCCIdentificationDataUpdate)
return
}
}
Expand All @@ -177,7 +177,7 @@ func (e *UCEVCC) evManufacturerDataUpdate(ski string, entity spineapi.EntityRemo

// Scenario 5
if _, err := evDeviceClassification.GetManufacturerDetails(); err == nil {
e.reader.SpineEvent(ski, entity, api.UCEVCCManufacturerDataUpdate)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCEVCCManufacturerDataUpdate)
}

}
Expand Down Expand Up @@ -209,5 +209,5 @@ func (e *UCEVCC) evElectricalPermittedValuesUpdate(ski string, entity spineapi.E
}

// Scenario 6
e.reader.SpineEvent(ski, entity, api.UCEVCCChargingPowerLimitsDataUpdate)
e.reader.SpineEvent(ski, entity.Device(), entity, api.UCEVCCChargingPowerLimitsDataUpdate)
}
2 changes: 1 addition & 1 deletion ucevcc/testhelper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ type UCEVCCSuite struct {
evEntity spineapi.EntityRemoteInterface
}

func (s *UCEVCCSuite) SpineEvent(ski string, entity spineapi.EntityRemoteInterface, event api.UseCaseEventType) {
func (s *UCEVCCSuite) SpineEvent(ski string, device spineapi.DeviceRemoteInterface, entity spineapi.EntityRemoteInterface, event api.UseCaseEventType) {
}

func (s *UCEVCCSuite) BeforeTest(suiteName, testName string) {
Expand Down
Loading

0 comments on commit a5ecbc0

Please sign in to comment.