Skip to content

Commit

Permalink
feat(#412): RSR-1048 add special case for InRef binding for LDEPF DIG…
Browse files Browse the repository at this point in the history
…ITAL BOOLEAN channels

Signed-off-by: massifben <105049157+massifben@users.noreply.github.com>
  • Loading branch information
massifben committed Aug 9, 2024
1 parent 837ff3f commit 606abc0
Show file tree
Hide file tree
Showing 3 changed files with 82 additions and 13 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,16 @@
import org.apache.commons.lang3.tuple.Pair;
import org.lfenergy.compas.scl2007b4.model.*;
import org.lfenergy.compas.sct.commons.dto.*;
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceActivation;
import org.lfenergy.compas.sct.commons.scl.ObjectReference;
import org.lfenergy.compas.sct.commons.scl.ied.InputsAdapter;
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceActivation;
import org.lfenergy.compas.sct.commons.scl.ldevice.LDeviceAdapter;
import org.lfenergy.compas.sct.commons.util.PrivateUtils;

import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

import static org.lfenergy.compas.sct.commons.util.CommonConstants.BEHAVIOUR_DO_NAME;
Expand Down Expand Up @@ -47,9 +48,6 @@
* <li>{@link LN0Adapter#getDAI <em>Returns the value of the <b>DataAttributeRef </b> containment reference By filter</em>}</li>
* <li>{@link LN0Adapter#getDAIValues(DataAttributeRef) <em>Returns <b>DAI (sGroup, value) </b> containment reference list By <b>DataAttributeRef </b> filter</em>}</li>
*
* <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>
*
* <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>
* <li>{@link LN0Adapter#addPrivate <em>Add <b>TPrivate </b>under this object</em>}</li>
* <li>{@link LN0Adapter#removeAllControlBlocksAndDatasets() <em>Remove all <b>ControlBlock</b></em>}</li>
* </ul>
Expand All @@ -75,6 +73,7 @@ public class LN0Adapter extends AbstractLNAdapter<LN0> {
public static final DaTypeName BEHAVIOUR_DA_TYPE_NAME = getDaTypeNameForBeh();
private static final String DAI_NAME_PURPOSE = "purpose";
private static final String INREF_PREFIX = "InRef";
private static final Pattern LDEFP_DIGITAL_CHANNEL_PATTERN = Pattern.compile("DYN_LDEPF_DIGITAL CHANNEL \\d+_\\d+_BOOLEAN");

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

private List<TExtRef> getExtRefsBoundToInRef(String desc) {
List<TExtRef> boundExtRefs = getBoundExtRefsByDesc(desc);
// Special case for LDEPF DIGITAL CHANNEL of type BOOLEAN RSR-1048
if (boundExtRefs.isEmpty() && LDEFP_DIGITAL_CHANNEL_PATTERN.matcher(desc).matches()) {
String descWithoutType = desc.substring(0, desc.lastIndexOf("_"));
return getBoundExtRefsByDesc(descWithoutType);
}
return boundExtRefs;
}

private List<TExtRef> getBoundExtRefsByDesc(String desc) {
return getExtRefs().stream()
.filter(tExtRef -> tExtRef.isSetIedName() && tExtRef.isSetLdInst() && tExtRef.isSetLnClass() && tExtRef.isSetDoName() &&
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -302,7 +302,7 @@ void getControlBlocksForMatchingFCDA_should_return_expected_Items(LN0 ln0, TServ
List<ControlBlock> controlBlocks = ln0Adapter.getControlBlocksForMatchingFCDA(extRefInfo).toList();
// Then
assertThat(controlBlocks).hasSize(1);
assertThat(controlBlocks.get(0).getServiceType()).isEqualTo(serviceType);
assertThat(controlBlocks.getFirst().getServiceType()).isEqualTo(serviceType);
}

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

@Test
Expand Down Expand Up @@ -434,7 +434,7 @@ void testFindMatch() {
// When Then
AbstractDAIAdapter<?> daiAdapter = (AbstractDAIAdapter<?>) assertDoesNotThrow(() -> ln0Adapter.findMatch(doTypeName, daTypeName).get());
assertThat(daiAdapter.getCurrentElem().getName()).isEqualTo("bda3");
assertThat(daiAdapter.getCurrentElem().getVal().get(0).getValue()).isEqualTo("Completed-diff");
assertThat(daiAdapter.getCurrentElem().getVal().getFirst().getValue()).isEqualTo("Completed-diff");
DoTypeName doTypeName2 = new DoTypeName("Do.sdo1");
// When Then
assertThat(ln0Adapter.findMatch(doTypeName2, daTypeName)).isEmpty();
Expand Down Expand Up @@ -540,7 +540,7 @@ void testGetDAI() {
var dataAttributeRefs = ln0Adapter.getDAI(filter, false);
// Then
assertThat(dataAttributeRefs).hasSize(1);
assertThat(dataAttributeRefs.get(0).getDaName().getType()).isEqualTo("BehaviourModeKind");
assertThat(dataAttributeRefs.getFirst().getDaName().getType()).isEqualTo("BehaviourModeKind");
}

@Test
Expand Down Expand Up @@ -864,7 +864,7 @@ void createControlBlockIfNotExists_should_create_SampledValueControl() {
// Then
assertThat(sourceLn0.getCurrentElem().getSampledValueControl())
.hasSize(1);
TSampledValueControl tSampledValueControl = sourceLn0.getCurrentElem().getSampledValueControl().get(0);
TSampledValueControl tSampledValueControl = sourceLn0.getCurrentElem().getSampledValueControl().getFirst();
assertThat(tSampledValueControl)
.extracting(TControl::getName, TSampledValueControl::getSmvID, TControl::getDatSet,
TSampledValueControl::isMulticast, TSampledValueControl::getSmpRate, TSampledValueControl::getNofASDU, TSampledValueControl::getSmpMod, TSampledValueControl::getSecurityEnable,
Expand Down Expand Up @@ -895,7 +895,7 @@ void createControlBlockIfNotExists_should_create_ReportControl() {
// Then
assertThat(sourceLn0.getCurrentElem().getReportControl())
.hasSize(1);
TReportControl tReportControl = sourceLn0.getCurrentElem().getReportControl().get(0);
TReportControl tReportControl = sourceLn0.getCurrentElem().getReportControl().getFirst();
assertThat(tReportControl)
.extracting(TControl::getName, TReportControl::getRptID, TControl::getDatSet,
TReportControl::isBuffered, TReportControl::getBufTime, TReportControl::isIndexed, TControlWithTriggerOpt::getIntgPd, TReportControl::getConfRev)
Expand Down Expand Up @@ -1140,6 +1140,42 @@ void updateDoInRef_when_ExtRef_desc_matches_should_update_setSrcRef_and_setSrcCB
assertThat(sclReportItems).isEmpty();
}

@Test
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() {
// Given
SCL scd = SclTestMarshaller.getSCLFromFile("/scd-test-update-inref/scd_update_inref_test.xml");
LN0Adapter sourceLn0 = findLn0(scd, "IED_NAME1", "LDEPF");
String doiNameInRef = "InRef3";
String originalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, SETSRCCB_DA_NAME);
String expectedSrcRef = "IED_NAME1LDEPF/PRANCR1.Do11.sdo11";
String expectedSrcCb = "IED_NAME1LDEPF/prefixANCR1.GSE1";
String originalSetTstCB = getDaiValue(sourceLn0, doiNameInRef, SETTSTCB_DA_NAME);
String expectedTstRef = "IED_NAME1LDEPF/PRANCR1.Do11.sdo11";
String expectedTstCB = "IED_NAME1LDEPF/prefixANCR3.GSE3";

// When
List<SclReportItem> sclReportItems = sourceLn0.updateDoInRef();
// Then

String finalSetSrcRef = getDaiValue(sourceLn0, doiNameInRef, SETSRCREF_DA_NAME);
String finalSetSrcCB = getDaiValue(sourceLn0, doiNameInRef, SETSRCCB_DA_NAME);
String finalSetTstRef = getDaiValue(sourceLn0, doiNameInRef, SETTSTREF_DA_NAME);
String finalSetTstCB = getDaiValue(sourceLn0, doiNameInRef, SETTSTCB_DA_NAME);
assertThat(finalSetSrcRef)
.isNotBlank()
.isEqualTo(expectedSrcRef);
assertThat(finalSetSrcCB)
.isNotEqualTo(originalSetSrcCB)
.isEqualTo(expectedSrcCb);
assertThat(finalSetTstRef)
.isNotBlank()
.isEqualTo(expectedTstRef);
assertThat(finalSetTstCB)
.isNotEqualTo(originalSetTstCB)
.isEqualTo(expectedTstCB);
assertThat(sclReportItems).isEmpty();
}

@Test
void updateDoInRef_when_ExtRef_desc_matches_and_dais_not_updatable_should_not_update_setSrcRef_and_setSrcCB_and_setTstRef_and_setTstCB() {
// Given
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,30 @@
</LN0>
</LDevice>

<!-- Case with LDEPF and DAI purpose ends with BOOLEAN matching the InRef with Enum -->
<LDevice inst="LDEPF" ldName="IED_NAME1LDEPF">
<LN0 lnClass="LLN0" inst="" lnType="LN11">
<DOI name="InRef3">
<DAI name="purpose">
<Val>DYN_LDEPF_DIGITAL CHANNEL 36_1_BOOLEAN</Val>
</DAI>
<DAI name="setSrcRef" valKind="RO" valImport="true"/>
<DAI name="setSrcCB" valKind="RO" valImport="true">
<Val>OLD_VAL</Val>
</DAI>
<DAI name="setTstRef" valKind="RO" valImport="true"/>
<DAI name="setTstCB" valKind="RO" valImport="true">
<Val>OLD_VAL</Val>
</DAI>
</DOI>
<Inputs>
<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"/>
<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"/>
<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"/>
</Inputs>
</LN0>
</LDevice>

<!-- Case with ExtRef.desc suffix not ending with "_1" -->
<LDevice inst="LD_WITH_1_Bad_InRef" ldName="IED_NAME1LD_INST12">
<LN0 lnClass="LLN0" inst="" lnType="LN11">
Expand Down Expand Up @@ -179,4 +203,4 @@
<DA name="purpose" bType="VisString255" fc="DC"/>
</DOType>
</DataTypeTemplates>
</SCL>
</SCL>

0 comments on commit 606abc0

Please sign in to comment.