Skip to content

Commit

Permalink
Merge branch 'dev' into feature/jsonrpc2
Browse files Browse the repository at this point in the history
  • Loading branch information
DerAndereAndi committed Nov 18, 2024
2 parents 73d0d7f + cec3695 commit 7adf380
Show file tree
Hide file tree
Showing 39 changed files with 276 additions and 77 deletions.
15 changes: 0 additions & 15 deletions api/usecases.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,18 +59,3 @@ type UseCaseInterface interface {
// add the features
AddFeatures()
}

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"`
}
46 changes: 46 additions & 0 deletions api/usecases_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package api

import (
"encoding/json"
"testing"

"github.com/enbility/spine-go/mocks"
"github.com/enbility/spine-go/model"
"github.com/enbility/spine-go/spine"

"github.com/stretchr/testify/assert"
)

func Test_RemoteEntityScenarios_Marshal(t *testing.T) {
item := RemoteEntityScenarios{
Entity: nil,
Scenarios: nil,
}
value, err := json.Marshal(item)
assert.Nil(t, err)
assert.NotNil(t, value)
assert.Equal(t, `{"Entity":null,"Scenarios":null}`, string(value))

item = RemoteEntityScenarios{
Entity: nil,
Scenarios: []uint{1, 2, 3},
}
value, err = json.Marshal(item)
assert.Nil(t, err)
assert.NotNil(t, value)
assert.Equal(t, `{"Entity":null,"Scenarios":[1,2,3]}`, string(value))

device := mocks.NewDeviceRemoteInterface(t)
deviceAddress := model.AddressDeviceType("test")
device.EXPECT().Address().Return(&deviceAddress).Times(1)
entity := spine.NewEntityRemote(device, model.EntityTypeTypeCEM, []model.AddressEntityType{1, 1})

item = RemoteEntityScenarios{
Entity: entity,
Scenarios: []uint{1, 2, 3},
}
value, err = json.Marshal(item)
assert.Nil(t, err)
assert.NotNil(t, value)
assert.Equal(t, `{"Entity":{"Device":"test","Entity":[1,1]},"Scenarios":[1,2,3]}`, string(value))
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module github.com/enbility/eebus-go
go 1.22.0

require (
github.com/enbility/ship-go v0.0.0-20241006160314-3a4325a1a6d6
github.com/enbility/spine-go v0.0.0-20241007182100-30ee8bc405a7
github.com/enbility/ship-go v0.0.0-20241118145930-d68708c5f1c0
github.com/enbility/spine-go v0.0.0-20241118145803-0589320ceced
github.com/stretchr/testify v1.9.0
golang.org/x/exp/jsonrpc2 v0.0.0-20240909161429-701f63a606c0
)
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/enbility/go-avahi v0.0.0-20240909195612-d5de6b280d7a h1:foChWb8lhzqa6lWDRs6COYMdp649YlUirFP8GqoT0JQ=
github.com/enbility/go-avahi v0.0.0-20240909195612-d5de6b280d7a/go.mod h1:H64mhYcAQUGUUnVqMdZQf93kPecH4M79xwH95Lddt3U=
github.com/enbility/ship-go v0.0.0-20241006160314-3a4325a1a6d6 h1:bjrcJ4wxEsG5rXHlXnedRzqAV9JYglj82S14Nf1oLvs=
github.com/enbility/ship-go v0.0.0-20241006160314-3a4325a1a6d6/go.mod h1:JJp8EQcJhUhTpZ2LSEU4rpdaM3E2n08tswWFWtmm/wU=
github.com/enbility/spine-go v0.0.0-20241007182100-30ee8bc405a7 h1:n6tv+YUMncSR9qxUs6k7d/YsKD9ujHHp5pUspIvM6sc=
github.com/enbility/spine-go v0.0.0-20241007182100-30ee8bc405a7/go.mod h1:ZoI9TaJO/So/677uknrli8sc6iryD7wC5iWhVIre+MI=
github.com/enbility/ship-go v0.0.0-20241118145930-d68708c5f1c0 h1:Z8j/N4DgUL8T8mINkHdq0bUbKcWtwDpno0bsKOGahPo=
github.com/enbility/ship-go v0.0.0-20241118145930-d68708c5f1c0/go.mod h1:JJp8EQcJhUhTpZ2LSEU4rpdaM3E2n08tswWFWtmm/wU=
github.com/enbility/spine-go v0.0.0-20241118145803-0589320ceced h1:Z2WrJ+ku7lPZqJ+uzqvIqdMpXqvAZRB3J3xW592pDXI=
github.com/enbility/spine-go v0.0.0-20241118145803-0589320ceced/go.mod h1:ZoI9TaJO/So/677uknrli8sc6iryD7wC5iWhVIre+MI=
github.com/enbility/zeroconf/v2 v2.0.0-20240920094356-be1cae74fda6 h1:XOYvxKtT1oxT37w/5oEiRLuPbm9FuJPt3fiYhX0h8Po=
github.com/enbility/zeroconf/v2 v2.0.0-20240920094356-be1cae74fda6/go.mod h1:BszP9qFV14mPXgyIREbgIdQtWxbAj3OKqvK02HihMoM=
github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
Expand Down
2 changes: 1 addition & 1 deletion usecases/api/cem_evcc.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ type CemEVCCInterface interface {
//
// parameters:
// - entity: the entity of the EV
ManufacturerData(entity spineapi.EntityRemoteInterface) (api.ManufacturerData, error)
ManufacturerData(entity spineapi.EntityRemoteInterface) (ManufacturerData, error)

// Scenario 6

Expand Down
2 changes: 1 addition & 1 deletion usecases/api/cem_evsecc.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ type CemEVSECCInterface interface {
// - entity: the entity of the EV
//
// returns deviceName, serialNumber, error
ManufacturerData(entity spineapi.EntityRemoteInterface) (api.ManufacturerData, error)
ManufacturerData(entity spineapi.EntityRemoteInterface) (ManufacturerData, error)

// the operating state data of an EVSE
//
Expand Down
16 changes: 16 additions & 0 deletions usecases/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ const (
EVChargeStateTypeFinished EVChargeStateType = "finished"
)

// manufacturer data type
type ManufacturerData struct {
DeviceName string
DeviceCode string
SerialNumber string
SoftwareRevision string
HardwareRevision string
VendorName string
VendorCode string
BrandName string
PowerSource string
ManufacturerNodeIdentification string
ManufacturerLabel string
ManufacturerDescription string
}

// Defines a phase specific limit data set
type LoadLimitsPhase struct {
Phase model.ElectricalConnectionPhaseNameType // the phase
Expand Down
3 changes: 2 additions & 1 deletion usecases/cem/cevc/public_scen2.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,9 @@ func (e *CEVC) WritePowerLimits(entity spineapi.EntityRemoteInterface, data []uc
for index, slot := range data {
relativeStart := totalDuration

slotid := uint(index) //nolint:gosec // disable G115
timeSeriesSlot := model.TimeSeriesSlotType{
TimeSeriesSlotId: util.Ptr(model.TimeSeriesSlotIdType(index)),
TimeSeriesSlotId: util.Ptr(model.TimeSeriesSlotIdType(slotid)),
TimePeriod: &model.TimePeriodType{
StartTime: model.NewAbsoluteOrRelativeTimeTypeFromDuration(relativeStart),
},
Expand Down
6 changes: 6 additions & 0 deletions usecases/cem/cevc/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ type CEVC struct {

var _ ucapi.CemCEVCInterface = (*CEVC)(nil)

// Add support for the Coordinated EV Charging (CEVC) use case
// as a CEM actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewCEVC(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *CEVC {
validActorTypes := []model.UseCaseActorType{
model.UseCaseActorTypeEV,
Expand Down
4 changes: 2 additions & 2 deletions usecases/cem/evcc/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -193,11 +193,11 @@ func (e *EVCC) Identifications(entity spineapi.EntityRemoteInterface) ([]ucapi.I
func (e *EVCC) ManufacturerData(
entity spineapi.EntityRemoteInterface,
) (
api.ManufacturerData,
ucapi.ManufacturerData,
error,
) {
if !e.IsCompatibleEntityType(entity) {
return api.ManufacturerData{}, api.ErrNoCompatibleEntity
return ucapi.ManufacturerData{}, api.ErrNoCompatibleEntity
}

return internal.ManufacturerData(e.LocalEntity, entity)
Expand Down
7 changes: 7 additions & 0 deletions usecases/cem/evcc/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,13 @@ type EVCC struct {

var _ ucapi.CemEVCCInterface = (*EVCC)(nil)

// Add support for the EV Commissioning and Configuration (EVCEM) use case
// as a CEM actor
//
// Parameters:
// - service: The service implementation
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewEVCC(
service api.ServiceInterface,
localEntity spineapi.EntityLocalInterface,
Expand Down
13 changes: 12 additions & 1 deletion usecases/cem/evcem/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,18 @@ type EVCEM struct {

var _ ucapi.CemEVCEMInterface = (*EVCEM)(nil)

func NewEVCEM(service api.ServiceInterface, localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *EVCEM {
// Add support for the Measurement of Electricity during EV Charging (EVCEM) use case
// as a CEM actor
//
// Parameters:
// - service: The service implementation
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewEVCEM(
service api.ServiceInterface,
localEntity spineapi.EntityLocalInterface,
eventCB api.EntityEventCallback,
) *EVCEM {
validActorTypes := []model.UseCaseActorType{
model.UseCaseActorTypeEV,
}
Expand Down
5 changes: 3 additions & 2 deletions usecases/cem/evsecc/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package evsecc
import (
"github.com/enbility/eebus-go/api"
"github.com/enbility/eebus-go/features/client"
ucapi "github.com/enbility/eebus-go/usecases/api"
"github.com/enbility/eebus-go/usecases/internal"
spineapi "github.com/enbility/spine-go/api"
"github.com/enbility/spine-go/model"
Expand All @@ -13,11 +14,11 @@ import (
func (e *EVSECC) ManufacturerData(
entity spineapi.EntityRemoteInterface,
) (
api.ManufacturerData,
ucapi.ManufacturerData,
error,
) {
if !e.IsCompatibleEntityType(entity) {
return api.ManufacturerData{}, api.ErrNoCompatibleEntity
return ucapi.ManufacturerData{}, api.ErrNoCompatibleEntity
}

return internal.ManufacturerData(e.LocalEntity, entity)
Expand Down
6 changes: 6 additions & 0 deletions usecases/cem/evsecc/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ type EVSECC struct {

var _ ucapi.CemEVSECCInterface = (*EVSECC)(nil)

// Add support for the EVSE Commmissioning and Configuration (EVSECC) use case
// as a CEM actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewEVSECC(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *EVSECC {
validActorTypes := []model.UseCaseActorType{
model.UseCaseActorTypeEVSE,
Expand Down
11 changes: 10 additions & 1 deletion usecases/cem/evsoc/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ type EVSOC struct {

var _ ucapi.CemEVSOCInterface = (*EVSOC)(nil)

// Add support for the EV State of Charge (EVSOC) use case
// as a CEM actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewEVSOC(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *EVSOC {
validActorTypes := []model.UseCaseActorType{
model.UseCaseActorTypeEV,
Expand Down Expand Up @@ -64,5 +70,8 @@ func (e *EVSOC) AddFeatures() {
}

func (e *EVSOC) UpdateUseCaseAvailability(available bool) {
e.LocalEntity.SetUseCaseAvailability(model.UseCaseActorTypeCEM, e.UseCaseName, available)
e.LocalEntity.SetUseCaseAvailability(model.UseCaseFilterType{
Actor: model.UseCaseActorTypeCEM,
UseCaseName: e.UseCaseName,
}, available)
}
7 changes: 7 additions & 0 deletions usecases/cem/opev/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ func (e *OPEV) HandleEvent(payload spineapi.EventPayload) {
}
}

// TODOS:
// - wie gehen wir damit um, wenn subscriptions nicht erfolgreich sind
// - wie gehen wir damit um, wenn bindings nicht erfolgreich sind, z.b. write implementierungen müssen prüfen ob ein binding exisiteirt
// könnte prüfen ob ein binding exisitert, wenn nicht gleich einen fehler zurückliefern
// - wie gehen wir damit um, wenn descriptions nicht abgefragt werden können
// - wie, wenn die einen Fehler zurückgeben

// an EV was connected
func (e *OPEV) evConnected(entity spineapi.EntityRemoteInterface) {
// initialise features, e.g. subscriptions, descriptions
Expand Down
6 changes: 5 additions & 1 deletion usecases/cem/opev/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,12 @@ func (e *OPEV) CurrentLimits(entity spineapi.EntityRemoteInterface) ([]float64,
// - limits: per phase data
//
// possible errors:
// - ErrDataNotAvailable if no such limit is (yet) available
// - ErrDataNotAvailable if none such limit is (yet) available
// - and others
//
// Notes:
// - If a limit of phase is not active, the value returned is set to the maximum permitted value (if available), otherwise the phase value is not returned
// - If at least one phase value is available, no error is returned
func (e *OPEV) LoadControlLimits(entity spineapi.EntityRemoteInterface) (
limits []ucapi.LoadLimitsPhase, resultErr error) {
if !e.IsCompatibleEntityType(entity) {
Expand Down
2 changes: 1 addition & 1 deletion usecases/cem/opev/public_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func (s *CemOPEVSuite) Test_Public() {
// The actual tests of the functionality is located in the util package
// The actual tests of the functionality is located in the internal package

_, _, _, err := s.sut.CurrentLimits(s.mockRemoteEntity)
assert.NotNil(s.T(), err)
Expand Down
6 changes: 6 additions & 0 deletions usecases/cem/opev/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ type OPEV struct {

var _ ucapi.CemOPEVInterface = (*OPEV)(nil)

// Add support for the Overload Protection by EV Charging Current Curtailment (OPEV) use case
// as a CEM actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewOPEV(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *OPEV {
validActorTypes := []model.UseCaseActorType{
model.UseCaseActorTypeEV,
Expand Down
2 changes: 1 addition & 1 deletion usecases/cem/oscev/public_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import (
)

func (s *CemOSCEVSuite) Test_Public() {
// The actual tests of the functionality is located in the util package
// The actual tests of the functionality is located in the internal package

_, _, _, err := s.sut.CurrentLimits(s.mockRemoteEntity)
assert.NotNil(s.T(), err)
Expand Down
6 changes: 6 additions & 0 deletions usecases/cem/oscev/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ type OSCEV struct {

var _ ucapi.CemOSCEVInterface = (*OSCEV)(nil)

// Add support for the Optimization of Self-Consumption during EV Charging (OSCEV) use case
// as a CEM actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewOSCEV(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *OSCEV {
validActorTypes := []model.UseCaseActorType{
model.UseCaseActorTypeEV,
Expand Down
6 changes: 6 additions & 0 deletions usecases/cem/vabd/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ type VABD struct {

var _ ucapi.CemVABDInterface = (*VABD)(nil)

// Add support for the Visualization of Aggregated Battery Data (VABD) use case
// as a CEM actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewVABD(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *VABD {
validActorTypes := []model.UseCaseActorType{
model.UseCaseActorTypeBatterySystem,
Expand Down
6 changes: 6 additions & 0 deletions usecases/cem/vapd/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,12 @@ type VAPD struct {

var _ ucapi.CemVAPDInterface = (*VAPD)(nil)

// Add support for the Visualization of Aggregated Photovoltaic Data (VAPD) use case
// as a CEM actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewVAPD(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *VAPD {
validActorTypes := []model.UseCaseActorType{
model.UseCaseActorTypePVSystem,
Expand Down
6 changes: 6 additions & 0 deletions usecases/cs/lpc/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ type LPC struct {

var _ ucapi.CsLPCInterface = (*LPC)(nil)

// Add support for the Limitation of Power Consumption (LPC) use case
// as a Controllable System actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewLPC(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *LPC {
validActorTypes := []model.UseCaseActorType{model.UseCaseActorTypeEnergyGuard}
validEntityTypes := []model.EntityTypeType{
Expand Down
2 changes: 1 addition & 1 deletion usecases/cs/lpp/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ const (
// E.g. going into or out of the Failsafe state
//
// Use Case LPP, Scenario 3
DataUpdateHeartbeat api.EventType = "uclpcserver-DataUpdateHeartbeat"
DataUpdateHeartbeat api.EventType = "cs-lpp-DataUpdateHeartbeat"
)
6 changes: 6 additions & 0 deletions usecases/cs/lpp/usecase.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,12 @@ type LPP struct {

var _ ucapi.CsLPPInterface = (*LPP)(nil)

// Add support for the Limitation of Power Production (LPC) use case
// as a Controllable System actor
//
// Parameters:
// - localEntity: The local entity which should support the use case
// - eventCB: The callback to be called when an event is triggered (optional, can be nil)
func NewLPP(localEntity spineapi.EntityLocalInterface, eventCB api.EntityEventCallback) *LPP {
validActorTypes := []model.UseCaseActorType{model.UseCaseActorTypeEnergyGuard}
validEntityTypes := []model.EntityTypeType{
Expand Down
Loading

0 comments on commit 7adf380

Please sign in to comment.