Skip to content

Commit 354b68d

Browse files
Merge pull request #416 from com-pas/feat/412-rsr-1048-key-management-for-ldepf-infref-binding
feat(#412): RSR-1048 add special case for InRef binding for LDEPF DIGITAL BOOLEAN channels
2 parents 61f51a7 + 606abc0 commit 354b68d

File tree

3 files changed

+82
-13
lines changed

3 files changed

+82
-13
lines changed

sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ln/LN0Adapter.java

+15-6
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,16 @@
88
import org.apache.commons.lang3.tuple.Pair;
99
import org.lfenergy.compas.scl2007b4.model.*;
1010
import org.lfenergy.compas.sct.commons.dto.*;
11-
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceActivation;
1211
import org.lfenergy.compas.sct.commons.scl.ObjectReference;
1312
import org.lfenergy.compas.sct.commons.scl.ied.InputsAdapter;
13+
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceActivation;
1414
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
1515
import org.lfenergy.compas.sct.commons.util.PrivateUtils;
1616

1717
import java.util.List;
1818
import java.util.Optional;
1919
import java.util.Set;
20+
import java.util.regex.Pattern;
2021
import java.util.stream.Collectors;
2122

2223
import static org.lfenergy.compas.sct.commons.util.CommonConstants.BEHAVIOUR_DO_NAME;
@@ -47,9 +48,6 @@
4748
* <li>{@link LN0Adapter#getDAI <em>Returns the value of the <b>DataAttributeRef </b> containment reference By filter</em>}</li>
4849
* <li>{@link LN0Adapter#getDAIValues(DataAttributeRef) <em>Returns <b>DAI (sGroup, value) </b> containment reference list By <b>DataAttributeRef </b> filter</em>}</li>
4950
*
50-
* <li>{@link LN0Adapter#getDataSetByName(String) <em>Returns the value of the <b>TDataSet </b>object reference By the value of the <b>name </b>attribute </em>}</li>
51-
*
52-
* <li>{@link LN0Adapter#getControlBlocks(List, TServiceType) <em>Returns the value of the <b>ControlBlock </b>containment reference list that match <b>datSet </b> value of given <b>TDataSet</b> </em>}</li>
5351
* <li>{@link LN0Adapter#addPrivate <em>Add <b>TPrivate </b>under this object</em>}</li>
5452
* <li>{@link LN0Adapter#removeAllControlBlocksAndDatasets() <em>Remove all <b>ControlBlock</b></em>}</li>
5553
* </ul>
@@ -75,6 +73,7 @@ public class LN0Adapter extends AbstractLNAdapter<LN0> {
7573
public static final DaTypeName BEHAVIOUR_DA_TYPE_NAME = getDaTypeNameForBeh();
7674
private static final String DAI_NAME_PURPOSE = "purpose";
7775
private static final String INREF_PREFIX = "InRef";
76+
private static final Pattern LDEFP_DIGITAL_CHANNEL_PATTERN = Pattern.compile("DYN_LDEPF_DIGITAL CHANNEL \\d+_\\d+_BOOLEAN");
7877

7978
/**
8079
* Constructor
@@ -188,7 +187,7 @@ public Optional<SclReportItem> updateLDeviceStatus(List<Pair<String, String>> ie
188187
if (daiBehList.isEmpty()) {
189188
return Optional.of(buildFatalReportItem("The LDevice doesn't have a DO @name='Beh' OR its associated DA@fc='ST' AND DA@name='stVal'"));
190189
}
191-
Set<String> enumValues = getEnumValues(daiBehList.get(0).getDaName().getType());
190+
Set<String> enumValues = getEnumValues(daiBehList.getFirst().getDaName().getType());
192191
Optional<TCompasLDevice> optionalTCompasLDevice = PrivateUtils.extractCompasPrivate(getParentAdapter().getCurrentElem(), TCompasLDevice.class);
193192
if (optionalTCompasLDevice.isEmpty()) {
194193
return Optional.of(buildFatalReportItem("The LDevice doesn't have a Private compas:LDevice."));
@@ -237,13 +236,23 @@ public List<SclReportItem> updateDoInRef() {
237236
&& doiAdapter.findDataAdapterByName(DAI_NAME_PURPOSE).isPresent())
238237
.map(doiAdapter -> doiAdapter.getDataAdapterByName(DAI_NAME_PURPOSE).getCurrentElem().getVal().stream()
239238
.findFirst()
240-
.map(tVal -> doiAdapter.updateDaiFromExtRef(getBoundExtRefsByDesc(tVal.getValue())))
239+
.map(tVal -> doiAdapter.updateDaiFromExtRef(getExtRefsBoundToInRef(tVal.getValue())))
241240
.orElse(List.of(SclReportItem.warning(getXPath(), "The DOI %s can't be bound with an ExtRef".formatted(getXPath()))))
242241
)
243242
.flatMap(List::stream)
244243
.collect(Collectors.toList());
245244
}
246245

246+
private List<TExtRef> getExtRefsBoundToInRef(String desc) {
247+
List<TExtRef> boundExtRefs = getBoundExtRefsByDesc(desc);
248+
// Special case for LDEPF DIGITAL CHANNEL of type BOOLEAN RSR-1048
249+
if (boundExtRefs.isEmpty() && LDEFP_DIGITAL_CHANNEL_PATTERN.matcher(desc).matches()) {
250+
String descWithoutType = desc.substring(0, desc.lastIndexOf("_"));
251+
return getBoundExtRefsByDesc(descWithoutType);
252+
}
253+
return boundExtRefs;
254+
}
255+
247256
private List<TExtRef> getBoundExtRefsByDesc(String desc) {
248257
return getExtRefs().stream()
249258
.filter(tExtRef -> tExtRef.isSetIedName() && tExtRef.isSetLdInst() && tExtRef.isSetLnClass() && tExtRef.isSetDoName() &&

sct-commons/src/test/java/org/lfenergy/compas/sct/commons/scl/ln/LN0AdapterTest.java

+42-6
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ void getControlBlocksForMatchingFCDA_should_return_expected_Items(LN0 ln0, TServ
302302
List<ControlBlock> controlBlocks = ln0Adapter.getControlBlocksForMatchingFCDA(extRefInfo).toList();
303303
// Then
304304
assertThat(controlBlocks).hasSize(1);
305-
assertThat(controlBlocks.get(0).getServiceType()).isEqualTo(serviceType);
305+
assertThat(controlBlocks.getFirst().getServiceType()).isEqualTo(serviceType);
306306
}
307307

308308
private static Stream<Arguments> provideServiceType() {
@@ -335,7 +335,7 @@ void getDOIAdapters_should_return_expected_list_of_DOIAdapter() {
335335
LN0Adapter ln0Adapter = new LN0Adapter(null, ln0);
336336
// When Then
337337
assertThat(ln0Adapter.getDOIAdapters()).isNotEmpty();
338-
assertThat(ln0Adapter.getDOIAdapters().get(0).getCurrentElem().getName()).isEqualTo("Do");
338+
assertThat(ln0Adapter.getDOIAdapters().getFirst().getCurrentElem().getName()).isEqualTo("Do");
339339
}
340340

341341
@Test
@@ -434,7 +434,7 @@ void testFindMatch() {
434434
// When Then
435435
AbstractDAIAdapter<?> daiAdapter = (AbstractDAIAdapter<?>) assertDoesNotThrow(() -> ln0Adapter.findMatch(doTypeName, daTypeName).get());
436436
assertThat(daiAdapter.getCurrentElem().getName()).isEqualTo("bda3");
437-
assertThat(daiAdapter.getCurrentElem().getVal().get(0).getValue()).isEqualTo("Completed-diff");
437+
assertThat(daiAdapter.getCurrentElem().getVal().getFirst().getValue()).isEqualTo("Completed-diff");
438438
DoTypeName doTypeName2 = new DoTypeName("Do.sdo1");
439439
// When Then
440440
assertThat(ln0Adapter.findMatch(doTypeName2, daTypeName)).isEmpty();
@@ -540,7 +540,7 @@ void testGetDAI() {
540540
var dataAttributeRefs = ln0Adapter.getDAI(filter, false);
541541
// Then
542542
assertThat(dataAttributeRefs).hasSize(1);
543-
assertThat(dataAttributeRefs.get(0).getDaName().getType()).isEqualTo("BehaviourModeKind");
543+
assertThat(dataAttributeRefs.getFirst().getDaName().getType()).isEqualTo("BehaviourModeKind");
544544
}
545545

546546
@Test
@@ -864,7 +864,7 @@ void createControlBlockIfNotExists_should_create_SampledValueControl() {
864864
// Then
865865
assertThat(sourceLn0.getCurrentElem().getSampledValueControl())
866866
.hasSize(1);
867-
TSampledValueControl tSampledValueControl = sourceLn0.getCurrentElem().getSampledValueControl().get(0);
867+
TSampledValueControl tSampledValueControl = sourceLn0.getCurrentElem().getSampledValueControl().getFirst();
868868
assertThat(tSampledValueControl)
869869
.extracting(TControl::getName, TSampledValueControl::getSmvID, TControl::getDatSet,
870870
TSampledValueControl::isMulticast, TSampledValueControl::getSmpRate, TSampledValueControl::getNofASDU, TSampledValueControl::getSmpMod, TSampledValueControl::getSecurityEnable,
@@ -895,7 +895,7 @@ void createControlBlockIfNotExists_should_create_ReportControl() {
895895
// Then
896896
assertThat(sourceLn0.getCurrentElem().getReportControl())
897897
.hasSize(1);
898-
TReportControl tReportControl = sourceLn0.getCurrentElem().getReportControl().get(0);
898+
TReportControl tReportControl = sourceLn0.getCurrentElem().getReportControl().getFirst();
899899
assertThat(tReportControl)
900900
.extracting(TControl::getName, TReportControl::getRptID, TControl::getDatSet,
901901
TReportControl::isBuffered, TReportControl::getBufTime, TReportControl::isIndexed, TControlWithTriggerOpt::getIntgPd, TReportControl::getConfRev)
@@ -1140,6 +1140,42 @@ void updateDoInRef_when_ExtRef_desc_matches_should_update_setSrcRef_and_setSrcCB
11401140
assertThat(sclReportItems).isEmpty();
11411141
}
11421142

1143+
@Test
1144+
void updateDoInRef_when_DAI_purpose_of_Ldevice_LDEPF_ends_with_BOOLEAN_should_match_desc_that_ends_with_enum_and_update_setSrcRef_and_setSrcCB_and_setTstRef_and_setTstCB() {
1145+
// Given
1146+
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
1147+
LN0Adapter sourceLn0 = findLn0(scd, "IED_NAME1", "LDEPF");
1148+
String doiNameInRef = "InRef3";
1149+
String originalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, SETSRCCB_DA_NAME);
1150+
String expectedSrcRef = "IED_NAME1LDEPF/PRANCR1.Do11.sdo11";
1151+
String expectedSrcCb = "IED_NAME1LDEPF/prefixANCR1.GSE1";
1152+
String originalSetTstCB = getDaiValue(sourceLn0, doiNameInRef, SETTSTCB_DA_NAME);
1153+
String expectedTstRef = "IED_NAME1LDEPF/PRANCR1.Do11.sdo11";
1154+
String expectedTstCB = "IED_NAME1LDEPF/prefixANCR3.GSE3";
1155+
1156+
// When
1157+
List<SclReportItem> sclReportItems = sourceLn0.updateDoInRef();
1158+
// Then
1159+
1160+
String finalSetSrcRef = getDaiValue(sourceLn0, doiNameInRef, SETSRCREF_DA_NAME);
1161+
String finalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, SETSRCCB_DA_NAME);
1162+
String finalSetTstRef = getDaiValue(sourceLn0, doiNameInRef, SETTSTREF_DA_NAME);
1163+
String finalSetTstCB = getDaiValue(sourceLn0, doiNameInRef, SETTSTCB_DA_NAME);
1164+
assertThat(finalSetSrcRef)
1165+
.isNotBlank()
1166+
.isEqualTo(expectedSrcRef);
1167+
assertThat(finalSetSrcCB)
1168+
.isNotEqualTo(originalSetSrcCB)
1169+
.isEqualTo(expectedSrcCb);
1170+
assertThat(finalSetTstRef)
1171+
.isNotBlank()
1172+
.isEqualTo(expectedTstRef);
1173+
assertThat(finalSetTstCB)
1174+
.isNotEqualTo(originalSetTstCB)
1175+
.isEqualTo(expectedTstCB);
1176+
assertThat(sclReportItems).isEmpty();
1177+
}
1178+
11431179
@Test
11441180
void updateDoInRef_when_ExtRef_desc_matches_and_dais_not_updatable_should_not_update_setSrcRef_and_setSrcCB_and_setTstRef_and_setTstCB() {
11451181
// Given

sct-commons/src/test/resources/scd-test-update-inref/scd_update_inref_test.xml

+25-1
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,30 @@
6767
</LN0>
6868
</LDevice>
6969

70+
<!-- Case with LDEPF and DAI purpose ends with BOOLEAN matching the InRef with Enum -->
71+
<LDevice inst="LDEPF" ldName="IED_NAME1LDEPF">
72+
<LN0 lnClass="LLN0" inst="" lnType="LN11">
73+
<DOI name="InRef3">
74+
<DAI name="purpose">
75+
<Val>DYN_LDEPF_DIGITAL CHANNEL 36_1_BOOLEAN</Val>
76+
</DAI>
77+
<DAI name="setSrcRef" valKind="RO" valImport="true"/>
78+
<DAI name="setSrcCB" valKind="RO" valImport="true">
79+
<Val>OLD_VAL</Val>
80+
</DAI>
81+
<DAI name="setTstRef" valKind="RO" valImport="true"/>
82+
<DAI name="setTstCB" valKind="RO" valImport="true">
83+
<Val>OLD_VAL</Val>
84+
</DAI>
85+
</DOI>
86+
<Inputs>
87+
<ExtRef iedName="IED_NAME1" desc="DYN_LDEPF_DIGITAL CHANNEL 36_1_FaultDirectionKind_13_dirGeneral_1" ldInst="LDEPF" lnClass="ANCR" lnInst="1" prefix="PR" intAddr="INT_ADDR11" pDO="Do11.sdo11" doName="Do11.sdo11" srcLDInst="LD22" srcCBName="GSE1" srcPrefix="prefix" srcLNClass="ANCR" srcLNInst="1"/>
88+
<ExtRef iedName="IED_NAME1" desc="DYN_LDEPF_DIGITAL CHANNEL 36_1_FaultDirectionKind_13_dirGeneral_2" ldInst="LDEPF" lnClass="ANCR" lnInst="1" prefix="PR" intAddr="INT_ADDR11" pDO="Do11.sdo11" doName="Do11.sdo11" srcLDInst="LD22" srcCBName="GSE2" srcPrefix="prefix" srcLNClass="ANCR" srcLNInst="2"/>
89+
<ExtRef iedName="IED_NAME1" desc="DYN_LDEPF_DIGITAL CHANNEL 36_1_FaultDirectionKind_13_dirGeneral_3" ldInst="LDEPF" lnClass="ANCR" lnInst="1" prefix="PR" intAddr="INT_ADDR11" pDO="Do11.sdo11" doName="Do11.sdo11" srcLDInst="LD22" srcCBName="GSE3" srcPrefix="prefix" srcLNClass="ANCR" srcLNInst="3"/>
90+
</Inputs>
91+
</LN0>
92+
</LDevice>
93+
7094
<!-- Case with ExtRef.desc suffix not ending with "_1" -->
7195
<LDevice inst="LD_WITH_1_Bad_InRef" ldName="IED_NAME1LD_INST12">
7296
<LN0 lnClass="LLN0" inst="" lnType="LN11">
@@ -179,4 +203,4 @@
179203
<DA name="purpose" bType="VisString255" fc="DC"/>
180204
</DOType>
181205
</DataTypeTemplates>
182-
</SCL>
206+
</SCL>

0 commit comments

Comments
 (0)