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

Commit

Permalink
Update events to use actual provided data
Browse files Browse the repository at this point in the history
Before data update events where triggered, whenever the data type was sent and the actual data item existed in the data storage. Which means that only updating a current measurement also triggered an update event for SoC if that was present in the store from an earlier update.

This is now changed and only considers the data elements that are actually provided in the payload.

Note: This does NOT consider if a datapoint has been deleted and not updated!
  • Loading branch information
DerAndereAndi committed May 13, 2024
1 parent d84105b commit 74909dd
Show file tree
Hide file tree
Showing 47 changed files with 827 additions and 288 deletions.
9 changes: 2 additions & 7 deletions ucevcc/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -128,18 +128,13 @@ func (e *UCEVCC) evConfigurationDescriptionDataUpdate(entity spineapi.EntityRemo

// the configuration key data of an EV was updated
func (e *UCEVCC) evConfigurationDataUpdate(payload spineapi.EventPayload) {
evDeviceConfiguration, err := util.DeviceConfiguration(e.service, payload.Entity)
if err != nil {
return
}

// Scenario 2
if _, err := evDeviceConfiguration.GetKeyValueForKeyName(model.DeviceConfigurationKeyNameTypeCommunicationsStandard, model.DeviceConfigurationKeyValueTypeTypeString); err == nil {
if util.DeviceConfigurationCheckDataPayloadForKeyName(false, e.service, payload, model.DeviceConfigurationKeyNameTypeCommunicationsStandard) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdateCommunicationStandard)
}

// Scenario 3
if _, err := evDeviceConfiguration.GetKeyValueForKeyName(model.DeviceConfigurationKeyNameTypeAsymmetricChargingSupported, model.DeviceConfigurationKeyValueTypeTypeString); err == nil {
if util.DeviceConfigurationCheckDataPayloadForKeyName(false, e.service, payload, model.DeviceConfigurationKeyNameTypeAsymmetricChargingSupported) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdateAsymmetricChargingSupport)
}
}
Expand Down
22 changes: 17 additions & 5 deletions ucevcc/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,11 +84,11 @@ func (s *UCEVCCSuite) Test_evConfigurationDataUpdate() {
descData := &model.DeviceConfigurationKeyValueDescriptionListDataType{
DeviceConfigurationKeyValueDescriptionData: []model.DeviceConfigurationKeyValueDescriptionDataType{
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(0)),
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(1)),
KeyName: eebusutil.Ptr(model.DeviceConfigurationKeyNameTypeCommunicationsStandard),
},
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(1)),
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(2)),
KeyName: eebusutil.Ptr(model.DeviceConfigurationKeyNameTypeAsymmetricChargingSupported),
},
},
Expand All @@ -102,24 +102,36 @@ func (s *UCEVCCSuite) Test_evConfigurationDataUpdate() {
assert.False(s.T(), s.eventCBInvoked)

data := &model.DeviceConfigurationKeyValueListDataType{
DeviceConfigurationKeyValueData: []model.DeviceConfigurationKeyValueDataType{},
}

payload.Data = data

s.sut.evConfigurationDataUpdate(payload)
assert.False(s.T(), s.eventCBInvoked)

data = &model.DeviceConfigurationKeyValueListDataType{
DeviceConfigurationKeyValueData: []model.DeviceConfigurationKeyValueDataType{
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(0)),
Value: eebusutil.Ptr(model.DeviceConfigurationKeyValueValueType{}),
},
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(1)),
Value: eebusutil.Ptr(model.DeviceConfigurationKeyValueValueType{
String: eebusutil.Ptr(model.DeviceConfigurationKeyValueStringTypeISO151182ED2),
}),
},
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(1)),
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(2)),
Value: eebusutil.Ptr(model.DeviceConfigurationKeyValueValueType{
Boolean: eebusutil.Ptr(false),
}),
},
},
}

fErr = rFeature.UpdateData(model.FunctionTypeDeviceConfigurationKeyValueListData, data, nil, nil)
assert.Nil(s.T(), fErr)
payload.Data = data

s.sut.evConfigurationDataUpdate(payload)
assert.True(s.T(), s.eventCBInvoked)
Expand Down
3 changes: 0 additions & 3 deletions ucevcc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,13 @@ const (
// - the entity of the EV
//
// Use Case EVCC, Scenario 2
// Note: the referred data may be updated together with all other configuration items of this use case
DataUpdateCommunicationStandard api.EventType = "DataUpdateCommunicationStandard"

// EV asymmetric charging data was updated
//
// The callback with this message provides:
// - the device of the EVSE the EV is connected to
// - the entity of the EV
//
// Note: the referred data may be updated together with all other configuration items of this use case
DataUpdateAsymmetricChargingSupport api.EventType = "DataUpdateAsymmetricChargingSupport"

// EV identificationdata was updated
Expand Down
17 changes: 12 additions & 5 deletions ucevcem/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,11 +73,18 @@ func (e *UCEVCEM) evConnected(entity spineapi.EntityRemoteInterface) {

// the electrical connection description data of an EV was updated
func (e *UCEVCEM) evElectricalConnectionDescriptionDataUpdate(payload spineapi.EventPayload) {
if _, err := e.PhasesConnected(payload.Entity); err != nil {
if payload.Data == nil {
return
}

e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdatePhasesConnected)
data := payload.Data.(*model.ElectricalConnectionDescriptionListDataType)

for _, item := range data.ElectricalConnectionDescriptionData {
if item.ElectricalConnectionId != nil && item.AcConnectedPhases != nil {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdatePhasesConnected)
return
}
}
}

// the measurement description data of an EV was updated
Expand All @@ -93,17 +100,17 @@ func (e *UCEVCEM) evMeasurementDescriptionDataUpdate(entity spineapi.EntityRemot
// the measurement data of an EV was updated
func (e *UCEVCEM) evMeasurementDataUpdate(payload spineapi.EventPayload) {
// Scenario 1
if _, err := util.MeasurementValueForScope(e.service, payload.Entity, model.ScopeTypeTypeACCurrent); err == nil {
if util.MeasurementCheckPayloadDataForScope(e.service, payload, model.ScopeTypeTypeACCurrent) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdateCurrentPerPhase)
}

// Scenario 2
if _, err := util.MeasurementValueForScope(e.service, payload.Entity, model.ScopeTypeTypeACPower); err == nil {
if util.MeasurementCheckPayloadDataForScope(e.service, payload, model.ScopeTypeTypeACPower) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdatePowerPerPhase)
}

// Scenario 3
if _, err := util.MeasurementValueForScope(e.service, payload.Entity, model.ScopeTypeTypeCharge); err == nil {
if util.MeasurementCheckPayloadDataForScope(e.service, payload, model.ScopeTypeTypeCharge) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdateEnergyCharged)
}
}
16 changes: 10 additions & 6 deletions ucevcem/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,14 @@ func (s *UCEVCEMSuite) Test_evElectricalConnectionDescriptionDataUpdate() {
s.sut.evElectricalConnectionDescriptionDataUpdate(payload)

descData := &model.ElectricalConnectionDescriptionListDataType{
ElectricalConnectionDescriptionData: []model.ElectricalConnectionDescriptionDataType{},
}

payload.Data = descData

s.sut.evElectricalConnectionDescriptionDataUpdate(payload)

descData = &model.ElectricalConnectionDescriptionListDataType{
ElectricalConnectionDescriptionData: []model.ElectricalConnectionDescriptionDataType{
{
ElectricalConnectionId: eebusutil.Ptr(model.ElectricalConnectionIdType(0)),
Expand All @@ -62,9 +70,7 @@ func (s *UCEVCEMSuite) Test_evElectricalConnectionDescriptionDataUpdate() {
},
}

rFeature := s.remoteDevice.FeatureByEntityTypeAndRole(s.evEntity, model.FeatureTypeTypeElectricalConnection, model.RoleTypeServer)
fErr := rFeature.UpdateData(model.FunctionTypeElectricalConnectionDescriptionListData, descData, nil, nil)
assert.Nil(s.T(), fErr)
payload.Data = descData

s.sut.evElectricalConnectionDescriptionDataUpdate(payload)
}
Expand Down Expand Up @@ -119,9 +125,7 @@ func (s *UCEVCEMSuite) Test_evMeasurementDataUpdate() {
},
},
}

fErr = rFeature.UpdateData(model.FunctionTypeMeasurementListData, data, nil, nil)
assert.Nil(s.T(), fErr)
payload.Data = data

s.sut.evMeasurementDataUpdate(payload)
}
8 changes: 0 additions & 8 deletions ucevcem/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ const (
// - the entity of the EV
//
// Use Case EVCEM, Scenario 1
//
// Note: the referred data may be updated together with all other measurement items of this use case
DataUpdatePhasesConnected api.EventType = "DataUpdatePhasesConnected"

// EV current measurement data updated
Expand All @@ -21,8 +19,6 @@ const (
// - the entity of the EV
//
// Use Case EVCEM, Scenario 1
//
// Note: the referred data may be updated together with all other measurement items of this use case
DataUpdateCurrentPerPhase api.EventType = "DataUpdateCurrentPerPhase"

// EV power measurement data updated
Expand All @@ -32,8 +28,6 @@ const (
// - the entity of the EV
//
// Use Case EVCEM, Scenario 2
//
// Note: the referred data may be updated together with all other measurement items of this use case
DataUpdatePowerPerPhase api.EventType = "DataUpdatePowerPerPhase"

// EV charging energy measurement data updated
Expand All @@ -43,7 +37,5 @@ const (
// - the entity of the EV
//
// Use Case EVCEM, Scenario 3
//
// Note: the referred data may be updated together with all other measurement items of this use case
DataUpdateEnergyCharged api.EventType = "DataUpdateEnergyCharged"
)
2 changes: 1 addition & 1 deletion ucevsoc/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func (e *UCEVSOC) evConnected(entity spineapi.EntityRemoteInterface) {
// the measurement data of an EV was updated
func (e *UCEVSOC) evMeasurementDataUpdate(payload spineapi.EventPayload) {
// Scenario 1
if _, err := util.MeasurementValueForScope(e.service, payload.Entity, model.ScopeTypeTypeStateOfCharge); err == nil {
if util.MeasurementCheckPayloadDataForScope(e.service, payload, model.ScopeTypeTypeStateOfCharge) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdateStateOfCharge)
}
}
3 changes: 1 addition & 2 deletions ucevsoc/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,8 +85,7 @@ func (s *UCEVSOCSuite) Test_evMeasurementDataUpdate() {
},
}

fErr = rFeature.UpdateData(model.FunctionTypeMeasurementListData, data, nil, nil)
assert.Nil(s.T(), fErr)
payload.Data = data

s.sut.evMeasurementDataUpdate(payload)
}
2 changes: 0 additions & 2 deletions ucevsoc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,5 @@ const (
// - the entity of the EV
//
// Use Case EVSOC, Scenario 1
//
// Note: the referred data may be updated together with all other measurement items of this use case
DataUpdateStateOfCharge api.EventType = "DataUpdateStateOfCharge"
)
31 changes: 8 additions & 23 deletions uclpc/events.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,28 +68,13 @@ func (e *UCLPC) loadControlLimitDescriptionDataUpdate(entity spineapi.EntityRemo

// the load control limit data was updated
func (e *UCLPC) loadControlLimitDataUpdate(payload spineapi.EventPayload) {
loadControl, err := util.LoadControl(e.service, payload.Entity)
if err != nil {
return
}

data, err := loadControl.GetLimitDescriptionsForCategory(model.LoadControlCategoryTypeObligation)
if err != nil {
return
}

for _, item := range data {
if item.LimitId == nil {
continue
}

_, err := loadControl.GetLimitValueForLimitId(*item.LimitId)
if err != nil {
continue
}

if util.LoadControlLimitsCheckPayloadDataForTypeCategoryDirectionScope(
false, e.service, payload,
model.LoadControlLimitTypeTypeSignDependentAbsValueLimit,
model.LoadControlCategoryTypeObligation,
model.EnergyDirectionTypeConsume,
model.ScopeTypeTypeActivePowerLimit) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdateLimit)
return
}
}

Expand All @@ -105,10 +90,10 @@ func (e *UCLPC) configurationDescriptionDataUpdate(entity spineapi.EntityRemoteI

// the configuration key data was updated
func (e *UCLPC) configurationDataUpdate(payload spineapi.EventPayload) {
if _, err := e.FailsafeConsumptionActivePowerLimit(payload.Entity); err != nil {
if util.DeviceConfigurationCheckDataPayloadForKeyName(false, e.service, payload, model.DeviceConfigurationKeyNameTypeFailsafeConsumptionActivePowerLimit) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdateFailsafeConsumptionActivePowerLimit)
}
if _, err := e.FailsafeDurationMinimum(payload.Entity); err != nil {
if util.DeviceConfigurationCheckDataPayloadForKeyName(false, e.service, payload, model.DeviceConfigurationKeyNameTypeFailsafeDurationMinimum) {
e.eventCB(payload.Ski, payload.Device, payload.Entity, DataUpdateFailsafeDurationMinimum)
}
}
71 changes: 67 additions & 4 deletions uclpc/events_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,11 @@ func (s *UCLPCSuite) Test_loadControlLimitDataUpdate() {
descData := &model.LoadControlLimitDescriptionListDataType{
LoadControlLimitDescriptionData: []model.LoadControlLimitDescriptionDataType{
{
LimitId: eebusutil.Ptr(model.LoadControlLimitIdType(0)),
LimitCategory: eebusutil.Ptr(model.LoadControlCategoryTypeObligation),
LimitId: eebusutil.Ptr(model.LoadControlLimitIdType(0)),
LimitType: eebusutil.Ptr(model.LoadControlLimitTypeTypeSignDependentAbsValueLimit),
LimitCategory: eebusutil.Ptr(model.LoadControlCategoryTypeObligation),
LimitDirection: eebusutil.Ptr(model.EnergyDirectionTypeConsume),
ScopeType: eebusutil.Ptr(model.ScopeTypeTypeActivePowerLimit),
},
},
}
Expand All @@ -69,6 +72,14 @@ func (s *UCLPCSuite) Test_loadControlLimitDataUpdate() {
s.sut.loadControlLimitDataUpdate(payload)

data := &model.LoadControlLimitListDataType{
LoadControlLimitData: []model.LoadControlLimitDataType{},
}

payload.Data = data

s.sut.loadControlLimitDataUpdate(payload)

data = &model.LoadControlLimitListDataType{
LoadControlLimitData: []model.LoadControlLimitDataType{
{
LimitId: eebusutil.Ptr(model.LoadControlLimitIdType(0)),
Expand All @@ -77,8 +88,60 @@ func (s *UCLPCSuite) Test_loadControlLimitDataUpdate() {
},
}

fErr = rFeature.UpdateData(model.FunctionTypeLoadControlLimitListData, data, nil, nil)
assert.Nil(s.T(), fErr)
payload.Data = data

s.sut.loadControlLimitDataUpdate(payload)
}

func (s *UCLPCSuite) Test_configurationDataUpdate() {
payload := spineapi.EventPayload{
Ski: remoteSki,
Device: s.remoteDevice,
Entity: s.monitoredEntity,
}
s.sut.configurationDataUpdate(payload)

descData := &model.DeviceConfigurationKeyValueDescriptionListDataType{
DeviceConfigurationKeyValueDescriptionData: []model.DeviceConfigurationKeyValueDescriptionDataType{
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(1)),
KeyName: eebusutil.Ptr(model.DeviceConfigurationKeyNameTypeFailsafeConsumptionActivePowerLimit),
},
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(2)),
KeyName: eebusutil.Ptr(model.DeviceConfigurationKeyNameTypeFailsafeDurationMinimum),
},
},
}

rFeature := s.remoteDevice.FeatureByEntityTypeAndRole(s.monitoredEntity, model.FeatureTypeTypeDeviceConfiguration, model.RoleTypeServer)
fErr := rFeature.UpdateData(model.FunctionTypeDeviceConfigurationKeyValueDescriptionListData, descData, nil, nil)
assert.Nil(s.T(), fErr)

s.sut.configurationDataUpdate(payload)

data := &model.DeviceConfigurationKeyValueListDataType{
DeviceConfigurationKeyValueData: []model.DeviceConfigurationKeyValueDataType{},
}

payload.Data = data

s.sut.configurationDataUpdate(payload)

data = &model.DeviceConfigurationKeyValueListDataType{
DeviceConfigurationKeyValueData: []model.DeviceConfigurationKeyValueDataType{
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(1)),
Value: &model.DeviceConfigurationKeyValueValueType{},
},
{
KeyId: eebusutil.Ptr(model.DeviceConfigurationKeyIdType(2)),
Value: &model.DeviceConfigurationKeyValueValueType{},
},
},
}

payload.Data = data

s.sut.configurationDataUpdate(payload)
}
4 changes: 0 additions & 4 deletions uclpc/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,6 @@ const (
// - the entity of the e.g. EVSE
//
// Use Case LPC, Scenario 2
//
// Note: the referred data may be updated together with all other configuration items of this use case
DataUpdateFailsafeConsumptionActivePowerLimit api.EventType = "DataUpdateFailsafeConsumptionActivePowerLimit"

// Minimum time the Controllable System remains in "failsafe state" unless conditions
Expand All @@ -32,7 +30,5 @@ const (
// - the entity of the e.g. EVSE
//
// Use Case LPC, Scenario 2
//
// Note: the referred data may be updated together with all other configuration items of this use case
DataUpdateFailsafeDurationMinimum api.EventType = "DataUpdateFailsafeDurationMinimum"
)
Loading

0 comments on commit 74909dd

Please sign in to comment.