Skip to content

Commit 19e3831

Browse files
Add workaround for PMCP reporting wrong uc address (#106)
The PMCP device reports EV usecases at the entity address of the EVSE entity (e.g. “[1]”), instead of the EV entity (e.g. “[1,1]”) This change checks for the actor type to be an EV and patches the address to include the EV subentity if it doesn’t have it
2 parents b779bca + 052de43 commit 19e3831

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

usecases/usecase/events.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,12 @@ func (u *UseCaseBase) useCaseDataUpdate(
6464
// if the address is given, use that for further checks
6565
if uc.Address != nil {
6666
ucEntity := remoteDevice.Entity(uc.Address.Entity)
67+
// the PMCP EVSE reports EV use cases with the address of the EVSE
68+
if *uc.Actor == model.UseCaseActorTypeEV && len(uc.Address.Entity) == 1 {
69+
// add the EV subentity to the address
70+
evAddress := append(uc.Address.Entity, 1)
71+
ucEntity = remoteDevice.Entity(evAddress)
72+
}
6773
if ucEntity != nil {
6874
entitiesToCheck = append(entitiesToCheck, ucEntity)
6975
}

usecases/usecase/events_test.go

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,3 +144,74 @@ func (s *UseCaseSuite) Test_useCaseDataUpdate() {
144144
result = s.uc.IsScenarioAvailableAtEntity(s.monitoredEntity, 1)
145145
assert.False(s.T(), result)
146146
}
147+
148+
func (s *UseCaseSuite) Test_useCaseDataUpdate_PMCP() {
149+
payload := spineapi.EventPayload{
150+
Device: s.remoteDevice,
151+
Entity: s.remoteDevice.Entities()[0],
152+
EventType: spineapi.EventTypeDataChange,
153+
ChangeType: spineapi.ElementChangeUpdate,
154+
Data: &model.NodeManagementUseCaseDataType{},
155+
}
156+
s.uc.useCaseDataUpdate(payload)
157+
158+
result := s.uc.IsScenarioAvailableAtEntity(s.monitoredEntity, 1)
159+
assert.False(s.T(), result)
160+
161+
address := &model.FeatureAddressType{
162+
Device: s.monitoredEntity.Device().Address(),
163+
Entity: []model.AddressEntityType{0},
164+
Feature: util.Ptr(model.AddressFeatureType(0)),
165+
}
166+
nodeFeature := s.remoteDevice.FeatureByAddress(address)
167+
168+
// the PMCP device reports the wrong entity address for the EV use cases :(
169+
data := &model.NodeManagementUseCaseDataType{
170+
UseCaseInformation: []model.UseCaseInformationDataType{
171+
{
172+
Address: &model.FeatureAddressType{
173+
Device: util.Ptr(model.AddressDeviceType("d:_i:19667_PorscheEVSE_0012345")),
174+
Entity: []model.AddressEntityType{1},
175+
},
176+
Actor: util.Ptr(model.UseCaseActorTypeEVSE),
177+
UseCaseSupport: []model.UseCaseSupportType{
178+
{
179+
UseCaseName: util.Ptr(model.UseCaseNameType("evseCommissioningAndConfiguration")),
180+
UseCaseVersion: util.Ptr(model.SpecificationVersionType("1.0.0")),
181+
ScenarioSupport: []model.UseCaseScenarioSupportType{1, 2},
182+
},
183+
},
184+
},
185+
{
186+
Address: &model.FeatureAddressType{
187+
Device: util.Ptr(model.AddressDeviceType("d:_i:19667_PorscheEVSE_0012345")),
188+
Entity: []model.AddressEntityType{1}, // this should include the subentity 1 to point to the EV entity
189+
},
190+
Actor: util.Ptr(model.UseCaseActorTypeEV),
191+
UseCaseSupport: []model.UseCaseSupportType{
192+
{
193+
UseCaseName: util.Ptr(model.UseCaseNameType("evCommissioningAndConfiguration")),
194+
UseCaseVersion: util.Ptr(model.SpecificationVersionType("1.0.0")),
195+
ScenarioSupport: []model.UseCaseScenarioSupportType{1, 2, 3, 6, 7, 8},
196+
},
197+
{
198+
UseCaseName: util.Ptr(model.UseCaseNameType("overloadProtectionByEvChargingCurrentCurtailment")),
199+
UseCaseVersion: util.Ptr(model.SpecificationVersionType("1.0.0")),
200+
ScenarioSupport: []model.UseCaseScenarioSupportType{1, 2, 3},
201+
},
202+
{
203+
UseCaseName: util.Ptr(model.UseCaseNameType("measurementOfElectricityDuringEvCharging")),
204+
UseCaseVersion: util.Ptr(model.SpecificationVersionType("1.0.0")),
205+
ScenarioSupport: []model.UseCaseScenarioSupportType{1},
206+
},
207+
},
208+
},
209+
},
210+
}
211+
nodeFeature.UpdateData(model.FunctionTypeNodeManagementUseCaseData, data, nil, nil)
212+
213+
s.uc.useCaseDataUpdate(payload)
214+
215+
result = s.uc.IsScenarioAvailableAtEntity(s.monitoredEntity, 1)
216+
assert.True(s.T(), result)
217+
}

0 commit comments

Comments
 (0)