Skip to content

Commit 569b00d

Browse files
Merge pull request #507 from com-pas/develop
Release 0.2.42
2 parents d44ead5 + cb36862 commit 569b00d

13 files changed

+1078
-574
lines changed

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/ExtRefEditorService.java

Lines changed: 68 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
package org.lfenergy.compas.sct.commons;
66

7+
import lombok.Getter;
78
import lombok.RequiredArgsConstructor;
89
import org.lfenergy.compas.scl2007b4.model.*;
910
import org.lfenergy.compas.sct.commons.api.ExtRefEditor;
@@ -15,6 +16,7 @@
1516
import org.lfenergy.compas.sct.commons.model.epf.TCBScopeType;
1617
import org.lfenergy.compas.sct.commons.model.epf.TChannel;
1718
import org.lfenergy.compas.sct.commons.model.epf.TChannelType;
19+
import org.lfenergy.compas.sct.commons.model.epf.TChannelLevMod;
1820
import org.lfenergy.compas.sct.commons.scl.SclRootAdapter;
1921
import org.lfenergy.compas.sct.commons.scl.ied.IEDAdapter;
2022
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
@@ -34,11 +36,20 @@
3436
@RequiredArgsConstructor
3537
public class ExtRefEditorService implements ExtRefEditor {
3638
private static final String INVALID_OR_MISSING_ATTRIBUTES_IN_EXT_REF_BINDING_INFO = "Invalid or missing attributes in ExtRef binding info";
39+
private static final String COMPAS_LNODE_STATUS = "COMPAS-LNodeStatus";
40+
private static final List<DoNameAndDaName> DO_DA_MAPPINGS = List.of(
41+
new DoNameAndDaName(CHNUM1_DO_NAME, DU_DA_NAME),
42+
new DoNameAndDaName(LEVMOD_DO_NAME, SETVAL_DA_NAME),
43+
new DoNameAndDaName(MOD_DO_NAME, STVAL_DA_NAME),
44+
new DoNameAndDaName(SRCREF_DO_NAME, SETSRCREF_DA_NAME)
45+
);
3746

3847
private final IedService iedService;
3948
private final LdeviceService ldeviceService;
4049
private final LnEditor lnEditor;
41-
private final DataTypeTemplatesService dataTypeTemplatesService;
50+
51+
@Getter
52+
private final List<SclReportItem> errorHandler = new ArrayList<>();
4253

4354
/**
4455
* Provides valid IED sources according to EPF configuration.<br/>
@@ -76,30 +87,21 @@ private List<TIED> getIedSources(SclRootAdapter sclRootAdapter, TCompasBay compa
7687
* - The location of ExtRef should be in LDevice (inst=LDEPF) <br/>
7788
* - ExtRef that lacks Bay or ICDHeader Private is not returned <br/>
7889
*
79-
* @param sclReportItems List of SclReportItem
8090
* @return list of ExtRef and associated Bay
8191
*/
82-
private List<ExtRefInfo.ExtRefWithBayReference> getExtRefWithBayReferenceInLDEPF(TDataTypeTemplates dataTypeTemplates, TIED tied, final TLDevice tlDevice, final List<SclReportItem> sclReportItems) {
83-
List<ExtRefInfo.ExtRefWithBayReference> extRefBayReferenceList = new ArrayList<>();
92+
private List<ExtRefInfo.ExtRefWithBayReference> getExtRefWithBayReferenceInLDEPF(TIED tied, final TLDevice tlDevice) {
8493
String lDevicePath = "SCL/IED[@name=\"" + tied.getName() + "\"]/AccessPoint/Server/LDevice[@inst=\"" + tlDevice.getInst() + "\"]";
8594
Optional<TCompasBay> tCompasBay = PrivateUtils.extractCompasPrivate(tied, TCompasBay.class);
8695
if (tCompasBay.isEmpty()) {
87-
sclReportItems.add(SclReportItem.error(lDevicePath, "The IED has no Private Bay"));
96+
errorHandler.add(SclReportItem.error(lDevicePath, "The IED has no Private Bay"));
8897
if (PrivateUtils.extractCompasPrivate(tied, TCompasICDHeader.class).isEmpty()) {
89-
sclReportItems.add(SclReportItem.error(lDevicePath, "The IED has no Private compas:ICDHeader"));
98+
errorHandler.add(SclReportItem.error(lDevicePath, "The IED has no Private compas:ICDHeader"));
9099
}
91100
return Collections.emptyList();
92101
}
93-
94-
if (dataTypeTemplatesService.isDoModAndDaStValExist(dataTypeTemplates, tlDevice.getLN0().getLnType())) {
95-
extRefBayReferenceList.addAll(tlDevice.getLN0()
96-
.getInputs()
97-
.getExtRef().stream()
98-
.map(extRef -> new ExtRefInfo.ExtRefWithBayReference(tied.getName(), tCompasBay.get(), extRef)).toList());
99-
} else {
100-
sclReportItems.add(SclReportItem.error(lDevicePath, "DO@name=Mod/DA@name=stVal not found in DataTypeTemplate"));
101-
}
102-
return extRefBayReferenceList;
102+
return tlDevice.getLN0().getInputs().getExtRef().stream()
103+
.map(extRef -> new ExtRefInfo.ExtRefWithBayReference(tied.getName(), tCompasBay.get(), extRef))
104+
.toList();
103105
}
104106

105107
/**
@@ -114,7 +116,7 @@ private static Boolean doesExtRefMatchLDEPFChannel(TExtRef extRef, TChannel tCha
114116
&& extRef.getDesc().startsWith("DYN_LDEPF_ANALOG CHANNEL " + tChannel.getChannelNum() + "_1_AnalogueValue")
115117
&& extRef.getDesc().endsWith("_" + tChannel.getDAName() + "_1");
116118
Boolean doesExtRefDescMatchDigitalChannel = tChannel.getChannelType().equals(TChannelType.DIGITAL)
117-
&& extRef.getDesc().startsWith("DYN_LDEPF_DIGITAL CHANNEL " + tChannel.getChannelNum() + "_1_BOOLEEN")
119+
&& extRef.getDesc().startsWith("DYN_LDEPF_DIGITAL CHANNEL " + tChannel.getChannelNum() + "_1_BOOLEAN")
118120
&& extRef.getDesc().endsWith("_" + tChannel.getDAName() + "_1");
119121
return extRef.isSetDesc() && (doesExtRefDescMatchAnalogChannel || doesExtRefDescMatchDigitalChannel)
120122
&& extRef.isSetPLN() && Utils.lnClassEquals(extRef.getPLN(), tChannel.getLNClass())
@@ -263,29 +265,30 @@ public TExtRef updateExtRefSource(SCL scd, ExtRefInfo extRefInfo) throws ScdExce
263265

264266
@Override
265267
public List<SclReportItem> manageBindingForLDEPF(SCL scd, EPF epf) {
266-
List<SclReportItem> sclReportItems = new ArrayList<>();
268+
errorHandler.clear();
267269
SclRootAdapter sclRootAdapter = new SclRootAdapter(scd);
268-
if (!epf.isSetChannels()) return sclReportItems;
270+
if (!epf.isSetChannels()) return errorHandler;
269271
iedService.getFilteredIeds(scd, ied -> !ied.getName().contains("TEST"))
270-
.forEach(tied -> ldeviceService.findLdevice(tied, LDEVICE_LDEPF)
271-
.ifPresent(tlDevice -> getExtRefWithBayReferenceInLDEPF(scd.getDataTypeTemplates(), tied, tlDevice, sclReportItems)
272+
.forEach(tied -> ldeviceService.findLdevice(tied, tlDevice -> tlDevice.getInst().equals(LDEVICE_LDEPF))
273+
.filter(ldepfLdevice -> PrivateUtils.extractStringPrivate(ldepfLdevice.getLN0(), COMPAS_LNODE_STATUS).map(status -> !status.equals("off")).orElse(false))
274+
.ifPresent(ldepfLdevice -> getExtRefWithBayReferenceInLDEPF(tied, ldepfLdevice)
272275
.forEach(extRefBayRef -> epf.getChannels().getChannel().stream().filter(tChannel -> doesExtRefMatchLDEPFChannel(extRefBayRef.extRef(), tChannel))
273276
.findFirst().ifPresent(channel -> {
274277
List<TIED> iedSources = getIedSources(sclRootAdapter, extRefBayRef.compasBay(), channel);
275278
if (iedSources.size() == 1) {
276-
updateLDEPFExtRefBinding(extRefBayRef.extRef(), iedSources.getFirst(), channel);
277-
LDeviceAdapter lDeviceAdapter = new LDeviceAdapter(new IEDAdapter(sclRootAdapter, tied.getName()), tlDevice);
278-
sclReportItems.addAll(updateLDEPFDos(lDeviceAdapter, extRefBayRef.extRef(), channel));
279+
updateLDEPFExtRefBinding(extRefBayRef, iedSources.getFirst(), channel);
280+
LDeviceAdapter lDeviceAdapter = new LDeviceAdapter(new IEDAdapter(sclRootAdapter, tied.getName()), ldepfLdevice);
281+
updateLDEPFDos(lDeviceAdapter, extRefBayRef.extRef(), channel);
279282
} else {
280283
if (iedSources.size() > 1) {
281-
sclReportItems.add(SclReportItem.warning(null, "There is more than one IED source to bind the signal " +
284+
errorHandler.add(SclReportItem.warning(null, "There is more than one IED source to bind the signal " +
282285
"/IED@name=" + extRefBayRef.iedName() + "/LDevice@inst=LDEPF/LN0" +
283286
"/ExtRef@desc=" + extRefBayRef.extRef().getDesc()));
284287
}
285288
// If the source IED is not found, there will be no update or report message.
286289
}
287290
}))));
288-
return sclReportItems;
291+
return errorHandler;
289292
}
290293

291294
@Override
@@ -320,56 +323,65 @@ public void epfPostProcessing(SCL scd) {
320323
})));
321324
}
322325

323-
private void updateLDEPFExtRefBinding(TExtRef extRef, TIED iedSource, TChannel setting) {
324-
extRef.setIedName(iedSource.getName());
325-
extRef.setLdInst(setting.getLDInst());
326-
extRef.getLnClass().add(setting.getLNClass());
327-
extRef.setLnInst(setting.getLNInst());
326+
private void updateLDEPFExtRefBinding(ExtRefInfo.ExtRefWithBayReference extRefWithBay, TIED iedSource, TChannel setting) {
327+
TExtRef tExtRef = extRefWithBay.extRef();
328+
tExtRef.setIedName(iedSource.getName());
329+
tExtRef.setLdInst(setting.getLDInst());
330+
tExtRef.getLnClass().add(setting.getLNClass());
331+
tExtRef.setLnInst(setting.getLNInst());
328332
if (!isBlank(setting.getLNPrefix())) {
329-
extRef.setPrefix(setting.getLNPrefix());
333+
tExtRef.setPrefix(setting.getLNPrefix());
330334
}
331335
String doName = isBlank(setting.getDOInst()) || setting.getDOInst().equals("0") ? setting.getDOName() : setting.getDOName() + setting.getDOInst();
332-
extRef.setDoName(doName);
336+
tExtRef.setDoName(doName);
337+
// This is true for External Binding
338+
if (!extRefWithBay.iedName().equals(iedSource.getName())) {
339+
tExtRef.setServiceType(
340+
switch (setting.getChannelType()) {
341+
case DIGITAL -> TServiceType.GOOSE;
342+
case ANALOG -> TServiceType.SMV;
343+
});
344+
}
333345
}
334346

335-
private List<SclReportItem> updateLDEPFDos(LDeviceAdapter lDeviceAdapter, TExtRef extRef, TChannel setting) {
336-
List<SclReportItem> sclReportItems = new ArrayList<>();
337-
List<DoNameAndDaName> doNameAndDaNameList = List.of(
338-
new DoNameAndDaName(CHNUM1_DO_NAME, DU_DA_NAME),
339-
new DoNameAndDaName(LEVMOD_DO_NAME, SETVAL_DA_NAME),
340-
new DoNameAndDaName(MOD_DO_NAME, STVAL_DA_NAME),
341-
new DoNameAndDaName(SRCREF_DO_NAME, SETSRCREF_DA_NAME)
342-
);
347+
private void updateLDEPFDos(LDeviceAdapter lDeviceAdapter, TExtRef extRef, TChannel setting) {
343348
if (setting.getChannelType().equals(TChannelType.DIGITAL)) {
344349
//digital
345350
lDeviceAdapter.findLnAdapter(LN_RBDR, setting.getChannelNum(), null)
346-
.ifPresent(lnAdapter -> doNameAndDaNameList.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName.doName, doNameAndDaName.daName, extRef, setting).ifPresent(sclReportItems::add)));
351+
.ifPresent(lnAdapter -> DO_DA_MAPPINGS.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName, extRef, setting)));
347352
lDeviceAdapter.findLnAdapter(LN_RBDR, setting.getChannelNum(), LN_PREFIX_B)
348-
.ifPresent(lnAdapter -> doNameAndDaNameList.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName.doName, doNameAndDaName.daName, extRef, setting).ifPresent(sclReportItems::add)));
353+
.ifPresent(lnAdapter -> DO_DA_MAPPINGS.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName, extRef, setting)));
349354
}
350355
if (setting.getChannelType().equals(TChannelType.ANALOG)) {
351356
//analog
352357
lDeviceAdapter.findLnAdapter(LN_RADR, setting.getChannelNum(), null)
353-
.ifPresent(lnAdapter -> doNameAndDaNameList.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName.doName, doNameAndDaName.daName, extRef, setting).ifPresent(sclReportItems::add)));
358+
.ifPresent(lnAdapter -> DO_DA_MAPPINGS.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName, extRef, setting)));
354359
lDeviceAdapter.findLnAdapter(LN_RADR, setting.getChannelNum(), LN_PREFIX_A)
355-
.ifPresent(lnAdapter -> doNameAndDaNameList.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName.doName, doNameAndDaName.daName, extRef, setting).ifPresent(sclReportItems::add)));
360+
.ifPresent(lnAdapter -> DO_DA_MAPPINGS.forEach(doNameAndDaName -> updateVal(lnAdapter, doNameAndDaName, extRef, setting)));
356361
}
357-
return sclReportItems;
358362
}
359363

360-
private Optional<SclReportItem> updateVal(AbstractLNAdapter<?> lnAdapter, String doName, String daName, TExtRef extRef, TChannel setting) {
361-
String value = switch (daName) {
362-
case DU_DA_NAME -> setting.getChannelShortLabel();
363-
case SETVAL_DA_NAME -> LN_PREFIX_B.equals(lnAdapter.getPrefix()) || LN_PREFIX_A.equals(lnAdapter.getPrefix()) ? setting.getChannelLevModQ().value() : setting.getChannelLevMod().value();
364-
case STVAL_DA_NAME -> ActiveStatus.ON.getValue();
365-
case SETSRCREF_DA_NAME -> computeDaiValue(lnAdapter, extRef, setting.getDAName());
366-
default -> null;
364+
private void updateVal(AbstractLNAdapter<?> lnAdapter, DoNameAndDaName doDaName, TExtRef extRef, TChannel setting) {
365+
String lnPrefix = lnAdapter.getPrefix();
366+
Optional<SclReportItem> sclReportItem = switch (doDaName.daName) {
367+
case DU_DA_NAME -> setting.isSetChannelShortLabel() ? lnAdapter.getDOIAdapterByName(doDaName.doName).updateDAI(doDaName.daName, setting.getChannelShortLabel()) :
368+
Optional.empty();
369+
case SETVAL_DA_NAME -> {
370+
if (LN_PREFIX_B.equals(lnPrefix) || LN_PREFIX_A.equals(lnPrefix)) {
371+
yield setting.isSetChannelLevModQ() && !setting.getChannelLevModQ().equals(TChannelLevMod.NA) ? lnAdapter.getDOIAdapterByName(doDaName.doName).updateDAI(doDaName.daName, setting.getChannelLevModQ().value()) : Optional.empty();
372+
} else {
373+
yield setting.isSetChannelLevMod() && !setting.getChannelLevMod().equals(TChannelLevMod.NA) ? lnAdapter.getDOIAdapterByName(doDaName.doName).updateDAI(doDaName.daName, setting.getChannelLevMod().value()) : Optional.empty();
374+
}
375+
}
376+
case STVAL_DA_NAME -> lnAdapter.getDOIAdapterByName(doDaName.doName).updateDAI(doDaName.daName, ActiveStatus.ON.getValue());
377+
case SETSRCREF_DA_NAME -> lnAdapter.getDOIAdapterByName(doDaName.doName).updateDAI(doDaName.daName, computeDaiValue(lnPrefix, extRef, setting.getDAName()));
378+
default -> throw new IllegalStateException("Unexpected value: " + doDaName.daName);
367379
};
368-
return lnAdapter.getDOIAdapterByName(doName).updateDAI(daName, value);
380+
sclReportItem.ifPresent(errorHandler::add);
369381
}
370382

371-
private String computeDaiValue(AbstractLNAdapter<?> lnAdapter, TExtRef extRef, String daName) {
372-
if (LN_PREFIX_B.equals(lnAdapter.getPrefix()) || LN_PREFIX_A.equals(lnAdapter.getPrefix())) {
383+
private String computeDaiValue(String lnPrefix, TExtRef extRef, String daName) {
384+
if (LN_PREFIX_B.equals(lnPrefix) || LN_PREFIX_A.equals(lnPrefix)) {
373385
return extRef.getIedName() +
374386
extRef.getLdInst() + "/" +
375387
trimToEmpty(extRef.getPrefix()) +

0 commit comments

Comments
 (0)