Skip to content
Open
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
5 changes: 3 additions & 2 deletions usecases/api/cem_evcem.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package api
import (
"github.com/enbility/eebus-go/api"
spineapi "github.com/enbility/spine-go/api"
"github.com/enbility/spine-go/model"
)

// Actor: Customer Energy Management
Expand All @@ -22,15 +23,15 @@ type CemEVCEMInterface interface {
//
// parameters:
// - entity: the entity of the EV
CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error)
CurrentPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error)

// Scenario 2

// return the last power measurement for each phase of the connected EV
//
// parameters:
// - entity: the entity of the EV
PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error)
PowerPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error)

// Scenario 3

Expand Down
5 changes: 3 additions & 2 deletions usecases/api/ma_mgcp.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package api
import (
"github.com/enbility/eebus-go/api"
spineapi "github.com/enbility/spine-go/api"
"github.com/enbility/spine-go/model"
)

// Actor: Monitoring Appliance
Expand Down Expand Up @@ -66,15 +67,15 @@ type MaMGCPInterface interface {
// return values:
// - positive values are used for consumption
// - negative values are used for production
CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error)
CurrentPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error)

// Scenario 6

// return the voltage phase details at the grid connection point
//
// parameters:
// - entity: the entity of the device (e.g. SMGW)
VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error)
VoltagePerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error)

// Scenario 7

Expand Down
7 changes: 4 additions & 3 deletions usecases/api/ma_mpc.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package api
import (
"github.com/enbility/eebus-go/api"
spineapi "github.com/enbility/spine-go/api"
"github.com/enbility/spine-go/model"
)

// Actor: Monitoring Appliance
Expand Down Expand Up @@ -30,7 +31,7 @@ type MaMPCInterface interface {
// possible errors:
// - ErrDataNotAvailable if no such limit is (yet) available
// - and others
PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error)
PowerPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error)

// Scenario 2

Expand Down Expand Up @@ -61,15 +62,15 @@ type MaMPCInterface interface {
// return values
// - positive values are used for consumption
// - negative values are used for production
CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error)
CurrentPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error)

// Scenario 4

// return the phase specific voltage details
//
// parameters:
// - entity: the entity of the device (e.g. EVSE)
VoltagePerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error)
VoltagePerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error)

// Scenario 5

Expand Down
12 changes: 6 additions & 6 deletions usecases/api/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ const (

type OptionalPowerConsumptionInfo struct {
PowerSequenceId model.PowerSequenceIdType
Power *float64
MaxPower *float64
State model.PowerSequenceStateType
IsPausable bool
IsStoppable bool
StartTime *time.Time
Power *float64
MaxPower *float64
State model.PowerSequenceStateType
IsPausable bool
IsStoppable bool
StartTime *time.Time
}

// manufacturer data type
Expand Down
17 changes: 7 additions & 10 deletions usecases/cem/evcem/public.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ func (e *EVCEM) PhasesConnected(entity spineapi.EntityRemoteInterface) (uint, er
// possible errors:
// - ErrDataNotAvailable if no such measurement is (yet) available
// - and others
func (e *EVCEM) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) {
func (e *EVCEM) CurrentPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) {
if !e.IsCompatibleEntityType(entity) {
return nil, api.ErrNoCompatibleEntity
}
Expand All @@ -61,7 +61,7 @@ func (e *EVCEM) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float6
return nil, api.ErrDataNotAvailable
}

var result []float64
result := make(map[model.ElectricalConnectionPhaseNameType]float64)

for _, phase := range ucapi.PhaseNameMapping {
for _, item := range data {
Expand All @@ -73,13 +73,11 @@ func (e *EVCEM) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float6
MeasurementId: item.MeasurementId,
}
elParam, err := evElectricalConnection.GetParameterDescriptionsForFilter(filter)
if err != nil || len(elParam) == 0 ||
elParam[0].AcMeasuredPhases == nil || *elParam[0].AcMeasuredPhases != phase {
if err != nil || len(elParam) == 0 || elParam[0].AcMeasuredPhases == nil || *elParam[0].AcMeasuredPhases != phase {
continue
}

phaseValue := item.Value.GetValue()
result = append(result, phaseValue)
result[phase] = item.Value.GetValue()
}
}

Expand All @@ -91,7 +89,7 @@ func (e *EVCEM) CurrentPerPhase(entity spineapi.EntityRemoteInterface) ([]float6
// possible errors:
// - ErrDataNotAvailable if no such measurement is (yet) available
// - and others
func (e *EVCEM) PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64, error) {
func (e *EVCEM) PowerPerPhase(entity spineapi.EntityRemoteInterface) (map[model.ElectricalConnectionPhaseNameType]float64, error) {
if !e.IsCompatibleEntityType(entity) {
return nil, api.ErrNoCompatibleEntity
}
Expand All @@ -115,7 +113,7 @@ func (e *EVCEM) PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64,
return nil, api.ErrDataNotAvailable
}

var result []float64
result := make(map[model.ElectricalConnectionPhaseNameType]float64)

for _, phase := range ucapi.PhaseNameMapping {
for _, item := range data {
Expand All @@ -133,8 +131,7 @@ func (e *EVCEM) PowerPerPhase(entity spineapi.EntityRemoteInterface) ([]float64,
continue
}

phaseValue := item.Value.GetValue()
result = append(result, phaseValue)
result[phase] = item.Value.GetValue()
}
}

Expand Down
160 changes: 153 additions & 7 deletions usecases/cem/evcem/public_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ func (s *CemEVCEMSuite) Test_EVCurrentPerPhase() {

data, err = s.sut.CurrentPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 10.0, data[0])
assert.Equal(s.T(), 10.0, data[model.ElectricalConnectionPhaseNameTypeA])

now := time.Now().Add(-50 * time.Second)

Expand All @@ -131,7 +131,7 @@ func (s *CemEVCEMSuite) Test_EVCurrentPerPhase() {

data, err = s.sut.CurrentPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 10.0, data[0])
assert.Equal(s.T(), 10.0, data[model.ElectricalConnectionPhaseNameTypeA])

now = now.Add(-1 * time.Hour)
measData = &model.MeasurementListDataType{
Expand All @@ -149,7 +149,7 @@ func (s *CemEVCEMSuite) Test_EVCurrentPerPhase() {

data, err = s.sut.CurrentPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 10.0, data[0])
assert.Equal(s.T(), 10.0, data[model.ElectricalConnectionPhaseNameTypeA])

now = now.Add(-1 * time.Hour)
measData = &model.MeasurementListDataType{
Expand All @@ -167,7 +167,7 @@ func (s *CemEVCEMSuite) Test_EVCurrentPerPhase() {

data, err = s.sut.CurrentPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 10.0, data[0])
assert.Equal(s.T(), 10.0, data[model.ElectricalConnectionPhaseNameTypeA])
}

func (s *CemEVCEMSuite) Test_EVCurrentPerPhase_AudiConnect() {
Expand Down Expand Up @@ -275,7 +275,7 @@ func (s *CemEVCEMSuite) Test_EVCurrentPerPhase_AudiConnect() {

data, err = s.sut.CurrentPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 10.0, data[0])
assert.Equal(s.T(), 10.0, data[model.ElectricalConnectionPhaseNameTypeA])

now := time.Now().Add(-50 * time.Second)

Expand Down Expand Up @@ -308,7 +308,7 @@ func (s *CemEVCEMSuite) Test_EVCurrentPerPhase_AudiConnect() {
data, err = s.sut.CurrentPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 1, len(data))
assert.Equal(s.T(), 10.0, data[0])
assert.Equal(s.T(), 10.0, data[model.ElectricalConnectionPhaseNameTypeA])
}

func (s *CemEVCEMSuite) Test_EVPowerPerPhase_Power() {
Expand Down Expand Up @@ -373,7 +373,7 @@ func (s *CemEVCEMSuite) Test_EVPowerPerPhase_Power() {

data, err = s.sut.PowerPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), 80.0, data[0])
assert.Equal(s.T(), 80.0, data[model.ElectricalConnectionPhaseNameTypeA])
}

func (s *CemEVCEMSuite) Test_EVPowerPerPhase_Current() {
Expand Down Expand Up @@ -553,6 +553,152 @@ func (s *CemEVCEMSuite) Test_EVPowerPerPhase_Current() {
assert.Equal(s.T(), 0, len(data))
}

func (s *CemEVCEMSuite) Test_EVPerPhaseMapsPhases() {
paramDesc := &model.ElectricalConnectionParameterDescriptionListDataType{
ElectricalConnectionParameterDescriptionData: []model.ElectricalConnectionParameterDescriptionDataType{
{
ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)),
ParameterId: util.Ptr(model.ElectricalConnectionParameterIdType(0)),
MeasurementId: util.Ptr(model.MeasurementIdType(12)),
ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent),
AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeA),
},
{
ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)),
ParameterId: util.Ptr(model.ElectricalConnectionParameterIdType(1)),
MeasurementId: util.Ptr(model.MeasurementIdType(10)),
ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent),
AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeB),
},
{
ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)),
ParameterId: util.Ptr(model.ElectricalConnectionParameterIdType(2)),
MeasurementId: util.Ptr(model.MeasurementIdType(11)),
ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent),
AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeC),
},
{
ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)),
ParameterId: util.Ptr(model.ElectricalConnectionParameterIdType(3)),
MeasurementId: util.Ptr(model.MeasurementIdType(22)),
ScopeType: util.Ptr(model.ScopeTypeTypeACPower),
AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeA),
},
{
ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)),
ParameterId: util.Ptr(model.ElectricalConnectionParameterIdType(4)),
MeasurementId: util.Ptr(model.MeasurementIdType(20)),
ScopeType: util.Ptr(model.ScopeTypeTypeACPower),
AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeB),
},
{
ElectricalConnectionId: util.Ptr(model.ElectricalConnectionIdType(0)),
ParameterId: util.Ptr(model.ElectricalConnectionParameterIdType(5)),
MeasurementId: util.Ptr(model.MeasurementIdType(21)),
ScopeType: util.Ptr(model.ScopeTypeTypeACPower),
AcMeasuredPhases: util.Ptr(model.ElectricalConnectionPhaseNameTypeC),
},
},
}

rFeature := s.remoteDevice.FeatureByEntityTypeAndRole(s.evEntity, model.FeatureTypeTypeElectricalConnection, model.RoleTypeServer)
_, fErr := rFeature.UpdateData(true, model.FunctionTypeElectricalConnectionParameterDescriptionListData, paramDesc, nil, nil)
assert.Nil(s.T(), fErr)

measDesc := &model.MeasurementDescriptionListDataType{
MeasurementDescriptionData: []model.MeasurementDescriptionDataType{
{
MeasurementId: util.Ptr(model.MeasurementIdType(12)),
MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent),
CommodityType: util.Ptr(model.CommodityTypeTypeElectricity),
ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(10)),
MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent),
CommodityType: util.Ptr(model.CommodityTypeTypeElectricity),
ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(11)),
MeasurementType: util.Ptr(model.MeasurementTypeTypeCurrent),
CommodityType: util.Ptr(model.CommodityTypeTypeElectricity),
ScopeType: util.Ptr(model.ScopeTypeTypeACCurrent),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(22)),
MeasurementType: util.Ptr(model.MeasurementTypeTypePower),
CommodityType: util.Ptr(model.CommodityTypeTypeElectricity),
ScopeType: util.Ptr(model.ScopeTypeTypeACPower),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(20)),
MeasurementType: util.Ptr(model.MeasurementTypeTypePower),
CommodityType: util.Ptr(model.CommodityTypeTypeElectricity),
ScopeType: util.Ptr(model.ScopeTypeTypeACPower),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(21)),
MeasurementType: util.Ptr(model.MeasurementTypeTypePower),
CommodityType: util.Ptr(model.CommodityTypeTypeElectricity),
ScopeType: util.Ptr(model.ScopeTypeTypeACPower),
},
},
}

rFeature = s.remoteDevice.FeatureByEntityTypeAndRole(s.evEntity, model.FeatureTypeTypeMeasurement, model.RoleTypeServer)
_, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementDescriptionListData, measDesc, nil, nil)
assert.Nil(s.T(), fErr)

measData := &model.MeasurementListDataType{
MeasurementData: []model.MeasurementDataType{
{
MeasurementId: util.Ptr(model.MeasurementIdType(20)),
Value: model.NewScaledNumberType(220),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(10)),
Value: model.NewScaledNumberType(10),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(22)),
Value: model.NewScaledNumberType(120),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(12)),
Value: model.NewScaledNumberType(12),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(21)),
Value: model.NewScaledNumberType(321),
},
{
MeasurementId: util.Ptr(model.MeasurementIdType(11)),
Value: model.NewScaledNumberType(11),
},
},
}

_, fErr = rFeature.UpdateData(true, model.FunctionTypeMeasurementListData, measData, nil, nil)
assert.Nil(s.T(), fErr)

currentData, err := s.sut.CurrentPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{
model.ElectricalConnectionPhaseNameTypeA: 12,
model.ElectricalConnectionPhaseNameTypeB: 10,
model.ElectricalConnectionPhaseNameTypeC: 11,
}, currentData)

powerData, err := s.sut.PowerPerPhase(s.evEntity)
assert.Nil(s.T(), err)
assert.Equal(s.T(), map[model.ElectricalConnectionPhaseNameType]float64{
model.ElectricalConnectionPhaseNameTypeA: 120,
model.ElectricalConnectionPhaseNameTypeB: 220,
model.ElectricalConnectionPhaseNameTypeC: 321,
}, powerData)
}

func (s *CemEVCEMSuite) Test_EVChargedEnergy() {
data, err := s.sut.EnergyCharged(s.mockRemoteEntity)
assert.NotNil(s.T(), err)
Expand Down
Loading
Loading