From a837d820c172830b79f98aac3eafe68fee44c059 Mon Sep 17 00:00:00 2001 From: massifben <105049157+massifben@users.noreply.github.com> Date: Mon, 16 Dec 2024 19:24:27 +0100 Subject: [PATCH] WIP --- .../sct/commons/DataTypeTemplatesService.java | 2 +- .../sct/commons/LNodeStatusService.java | 111 ++--- .../compas/sct/commons/util/PrivateUtils.java | 10 + .../sct/commons/LNodeStatusServiceTest.java | 31 +- .../sct/commons/testhelpers/SclHelper.java | 469 +++++++++--------- .../resources/scl-lnodestatus/lnodestatus.scd | 23 +- 6 files changed, 339 insertions(+), 307 deletions(-) diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/DataTypeTemplatesService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/DataTypeTemplatesService.java index c9ebe73f9..3e6c643ab 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/DataTypeTemplatesService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/DataTypeTemplatesService.java @@ -109,7 +109,7 @@ public Optional findDoLinkedToDa(TDataTypeTemplates dtt, String lN // Prepare DataObject DataObject dataObject = new DataObject(tdo.getName(), tdoType.getCdc(), doLinkedToDaFilter.sdoNames()); // Search first DA from last DoType - return sdoOrDAService.findDA(lastDoType, tda1 -> tda1.getName().equals(doLinkedToDaFilter.daName())) + return sdoOrDAService.findDA(lastDoType, tda -> tda.getName().equals(doLinkedToDaFilter.daName())) .flatMap(tda -> { // Prepare DataAttribute DataAttribute dataAttribute = new DataAttribute(); diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/LNodeStatusService.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/LNodeStatusService.java index b53cecb05..a5f2c1e04 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/LNodeStatusService.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/LNodeStatusService.java @@ -4,22 +4,24 @@ package org.lfenergy.compas.sct.commons; -import org.apache.commons.lang3.StringUtils; -import org.lfenergy.compas.scl2007b4.model.SCL; -import org.lfenergy.compas.scl2007b4.model.TAnyLN; -import org.lfenergy.compas.scl2007b4.model.TBaseElement; -import org.lfenergy.compas.scl2007b4.model.TPredefinedBasicTypeEnum; +import org.lfenergy.compas.scl2007b4.model.*; import org.lfenergy.compas.sct.commons.domain.DataAttribute; import org.lfenergy.compas.sct.commons.domain.DoLinkedToDa; import org.lfenergy.compas.sct.commons.domain.DoLinkedToDaFilter; import org.lfenergy.compas.sct.commons.dto.SclReportItem; import org.lfenergy.compas.sct.commons.util.CommonConstants; +import org.lfenergy.compas.sct.commons.util.PrivateUtils; +import org.lfenergy.compas.sct.commons.util.SclConstructorHelper; import java.util.List; import java.util.Optional; +import java.util.stream.Stream; public class LNodeStatusService { + private static final String ON = "on"; + private static final String OFF = "off"; + private static final String LNODE_STATUS_PRIVATE_TYPE = "COMPAS-LNodeStatus"; private final LnService lnService = new LnService(); private final DataTypeTemplatesService dataTypeTemplatesService = new DataTypeTemplatesService(); @@ -30,62 +32,59 @@ public List updateLnModStValBasedOnLNodeStatus(SCL scl) { .flatMap(tBay -> tBay.getFunction().stream()) .flatMap(tFunction -> tFunction.getLNode().stream()) .map(tlNode -> { - String lNodeLnodeStatus = extractStringPrivate(tlNode, "COMPAS-LNodeStatus") - .orElseThrow(); // FIXME - TAnyLN tAnyLN = findLn(scl, tlNode.getIedName(), tlNode.getLdInst(), tlNode.getLnClass().getFirst(), tlNode.getLnInst(), tlNode.getPrefix()) - .orElseThrow();// FIXME - String lnLNodeStatus = extractStringPrivate(tAnyLN, "COMPAS-LNodeStatus") - .orElseThrow(); - switch (lNodeLnodeStatus) { - case "on" -> { - if (lnLNodeStatus.contains("on")) { - // Met à jour Mod stVal s'il existe - lnService.getDaiModStVal(tAnyLN) - .ifPresent(tdai -> { + String lNodeLNS = PrivateUtils.extractStringPrivate(tlNode, LNODE_STATUS_PRIVATE_TYPE) + .orElseThrow(); // FIXME + TAnyLN anyLn = findLn(scl, tlNode.getIedName(), tlNode.getLdInst(), tlNode.getLnClass().getFirst(), tlNode.getLnInst(), tlNode.getPrefix()) + .orElseThrow(() -> new RuntimeException("Aucun LN trouvé dans l'IED %s, LD %s, LN %s,%s,%s".formatted(tlNode.getIedName(), tlNode.getLdInst(), tlNode.getLnClass().getFirst(), tlNode.getLnInst(), tlNode.getPrefix())));// FIXME + String anyLnLNS = PrivateUtils.extractStringPrivate(anyLn, LNODE_STATUS_PRIVATE_TYPE) + .orElseThrow(); + if (!lNodeLNS.equals(ON) && !lNodeLNS.equals(OFF)) { + throw new RuntimeException("FIXME"); + } - dataTypeTemplatesService.findDoLinkedToDa(scl.getDataTypeTemplates(), tAnyLN.getLnType(), DoLinkedToDaFilter.from(CommonConstants.MOD_DO_NAME, CommonConstants.STVAL_DA_NAME)) - .map(DoLinkedToDa::dataAttribute) - .filter(dataAttribute -> TPredefinedBasicTypeEnum.ENUM.equals(dataAttribute.getBType())) - .map(DataAttribute::getType); - }); - } else { - // erreur // FIXME - } - } - case "of" -> { - if (lnLNodeStatus.contains("off")) { - // Met à jour Mod stVal s'il existe - } else { - // erreur // FIXME - } - } - default -> { - // erreur // FIXME - } - } - return null; - } - ); + if (anyLnLNS.contains(lNodeLNS)) { + // Met à jour Mod stVal s'il existe + lnService.getDaiModStVal(anyLn) + .ifPresent(tdai -> getModStValEnumValues(scl.getDataTypeTemplates(), anyLn.getLnType()) + .filter(lNodeLNS::equals) + .findFirst() + .ifPresentOrElse(ignored -> { + tdai.unsetVal(); + tdai.getVal().add(SclConstructorHelper.newVal(lNodeLNS)); + }, + () -> { + throw new RuntimeException("FIXME"); + })); + } else { + throw new RuntimeException("FIXME"); + } + return null; + }) + .toList(); return List.of(); - } +} - private static Optional extractStringPrivate(TBaseElement tBaseElement, String privateType) { - return tBaseElement.getPrivate().stream() - .filter(tPrivate -> privateType.equals(tPrivate.getType())) - .flatMap(tPrivate -> tPrivate.getContent().stream()) - .filter(String.class::isInstance) - .map(String.class::cast) - .filter(StringUtils::isNotBlank) - .findFirst(); - } +private Stream getModStValEnumValues(TDataTypeTemplates dataTypeTemplates, String lnType) { + return dataTypeTemplatesService.findDoLinkedToDa(dataTypeTemplates, lnType, DoLinkedToDaFilter.from(CommonConstants.MOD_DO_NAME, CommonConstants.STVAL_DA_NAME)) + .map(DoLinkedToDa::dataAttribute) + .filter(dataAttribute -> TPredefinedBasicTypeEnum.ENUM.equals(dataAttribute.getBType())) + .map(DataAttribute::getType) + .flatMap(enumId -> + dataTypeTemplates.getEnumType().stream() + .filter(tEnumType -> tEnumType.getId().equals(enumId)) + .findFirst()) + .stream() + .flatMap(tEnumType -> tEnumType.getEnumVal().stream()) + .map(TEnumVal::getValue); +} private Optional findLn(SCL scl, String iedName, String ldInst, String lnClass, String lnInst, String prefix) { - return scl.getIED().stream() - .filter(tied -> iedName.equals(tied.getName())) - .findFirst() - .flatMap(tied -> new LdeviceService().findLdevice(tied, tlDevice -> ldInst.equals(tlDevice.getInst()))) - .flatMap(tlDevice -> lnService.findAnyLn(tlDevice, tAnyLN -> lnService.matchesLn(tAnyLN, lnInst, lnClass, prefix))); + return scl.getIED().stream() + .filter(tied -> iedName.equals(tied.getName())) + .findFirst() + .flatMap(tied -> new LdeviceService().findLdevice(tied, tlDevice -> ldInst.equals(tlDevice.getInst()))) + .flatMap(tlDevice -> lnService.findAnyLn(tlDevice, tAnyLN -> lnService.matchesLn(tAnyLN, lnClass, lnInst, prefix))); - } +} } diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/PrivateUtils.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/PrivateUtils.java index 049f1e48a..8d9cbfde1 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/PrivateUtils.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/util/PrivateUtils.java @@ -7,6 +7,7 @@ import jakarta.xml.bind.JAXBElement; import lombok.NonNull; import lombok.experimental.UtilityClass; +import org.apache.commons.lang3.StringUtils; import org.lfenergy.compas.scl2007b4.model.*; import org.lfenergy.compas.sct.commons.dto.PrivateLinkedToStds; import org.lfenergy.compas.sct.commons.exception.ScdException; @@ -320,4 +321,13 @@ public static void copyCompasICDHeaderFromLNodePrivateIntoSTDPrivate(TPrivate st } + public static Optional extractStringPrivate(TBaseElement tBaseElement, String privateType) { + return tBaseElement.getPrivate().stream() + .filter(tPrivate -> privateType.equals(tPrivate.getType())) + .flatMap(tPrivate -> tPrivate.getContent().stream()) + .filter(String.class::isInstance) + .map(String.class::cast) + .filter(StringUtils::isNotBlank) + .findFirst(); } +} diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/LNodeStatusServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/LNodeStatusServiceTest.java index 42ba782ca..86a6f5484 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/LNodeStatusServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/LNodeStatusServiceTest.java @@ -5,15 +5,19 @@ package org.lfenergy.compas.sct.commons; import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.lfenergy.compas.scl2007b4.model.SCL; import org.lfenergy.compas.sct.commons.dto.SclReportItem; +import org.lfenergy.compas.sct.commons.testhelpers.SclHelper; import org.lfenergy.compas.sct.commons.testhelpers.SclTestMarshaller; import java.util.List; +import java.util.stream.Stream; import static org.assertj.core.api.Assertions.assertThat; -import static org.junit.jupiter.api.Assertions.*; +import static org.junit.jupiter.api.Named.named; import static org.lfenergy.compas.sct.commons.testhelpers.SclHelper.*; class LNodeStatusServiceTest { @@ -25,16 +29,31 @@ void setUp() throws Exception { lNodeStatusService = new LNodeStatusService(); } - @Test - void updateLnStatusBasedOnPrivateLNodeStatus_should_succeed() { + @ParameterizedTest + @MethodSource("provideUpdateModStVal") + void updateLnStatusBasedOnPrivateLNodeStatus_should_update_Mod_stVal(String ldInst, String lnClass, String lnInst, String expected) { // Given SCL scl = SclTestMarshaller.getSCLFromFile("/scl-lnodestatus/lnodestatus.scd"); // When List sclReportItems = lNodeStatusService.updateLnModStValBasedOnLNodeStatus(scl); // Then assertThat(sclReportItems).isEmpty(); - assertThat(getValue(findDai(findLn(scl, "IED_NAME_1", "LDEVICE_1", "PDIS", "1", ""), "Mod.stVal"))) - .isEqualTo("on"); + assertThat(findDai(scl, "IED_NAME_1", ldInst, lnClass, lnInst, "", "Mod", "stVal")) + .map(SclHelper::getValue) + .hasValue(expected); + } + + public static Stream provideUpdateModStVal() { + return Stream.of( + Arguments.of(named("LN 'on' à mettre à 'on'", "LDEVICE_1"), "PDIS", "1", "on"), + Arguments.of(named("LN 'off;on' à mettre à 'on'", "LDEVICE_1"), "PDIS", "2", "on"), + Arguments.of(named("LN 'off' à mettre à 'off'", "LDEVICE_1"), "PDIS", "3", "off"), + Arguments.of(named("LN 'off;on' à mettre à 'off'", "LDEVICE_1"), "PDIS", "3", "off"), + Arguments.of(named("LN0 'on' à mettre à 'on'", "LDEVICE_1"), "LLN0", "", "on"), + Arguments.of(named("LN0 'off;on' à mettre à 'on'", "LDEVICE_2"), "LLN0", "", "on"), + Arguments.of(named("LN0 'off' à mettre à 'off'", "LDEVICE_3"), "LLN0", "", "off"), + Arguments.of(named("LN0 'off;on' à mettre à 'off'", "LDEVICE_4"), "LLN0", "", "off") + ); } diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java index 0d843c335..3eff083cc 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/testhelpers/SclHelper.java @@ -21,6 +21,7 @@ import java.util.Optional; import java.util.stream.Stream; +import static org.apache.commons.lang3.StringUtils.trimToEmpty; import static org.assertj.core.api.Assertions.assertThat; import static org.lfenergy.compas.sct.commons.util.SclConstructorHelper.newConnectedAp; import static org.lfenergy.compas.sct.commons.util.Utils.lnClassEquals; @@ -99,257 +100,275 @@ public static LNAdapter findLn(SCL scl, String iedName, String ldInst, String ln ); } - public static IDataParentAdapter findDoiOrSdi(AbstractLNAdapter lnAdapter, String dataTypeRef) { - if (dataTypeRef.length() < 1) { - Assertions.fail("dataTypeRef must at least contain a DO, but got: " + dataTypeRef); - } - String[] names = dataTypeRef.split("\\."); - IDataParentAdapter parentAdapter = lnAdapter.getDOIAdapterByName(names[0]); - for (int i = 1; i < names.length; i++) { - parentAdapter = parentAdapter.getStructuredDataAdapterByName(names[i]); + public static TAnyLN findAnyLn(SCL scl, String iedName, String ldInst, String lnClass, String lnInst, String prefix) { + TLDevice tlDevice = scl.getIED().stream().filter(tied -> tied.getName().equals(iedName)) + .findFirst().orElseThrow(() -> new AssertionFailedError("IED with name=%s not found".formatted(iedName))) + .getAccessPoint().stream() + .flatMap(tAccessPoint -> tAccessPoint.getServer().getLDevice().stream()) + .filter(tlDevice1 -> tlDevice1.getInst().equals(ldInst)) + .findFirst().orElseThrow(() -> new AssertionFailedError("LDevice with inst=%s not found".formatted(ldInst))); + if (lnClass.equals(TLLN0Enum.LLN_0.value()) && tlDevice.isSetLN0()) { + return tlDevice.getLN0(); } - return parentAdapter; + return tlDevice.getLN().stream() + .filter(tln -> Utils.lnClassEquals(tln.getLnClass(), lnClass) && trimToEmpty(tln.getInst()).equals(trimToEmpty(lnInst)) && trimToEmpty(tln.getPrefix()).equals(trimToEmpty(prefix))) + .findFirst() + .orElseThrow(() -> new AssertionFailedError("LN (lnClass=%s, lnInst=%s, lnPrefix=%s) not found".formatted(lnClass, lnInst, prefix))); } - public static Optional findDai(SCL scl, String iedName, String ldInst, String doiName, String daiName) { - return scl.getIED().stream().filter(tied -> tied.getName().equals(iedName)) - .flatMap(tied -> tied.getAccessPoint().stream()) - .flatMap(tAccessPoint -> tAccessPoint.getServer().getLDevice().stream()) - .filter(tlDevice -> tlDevice.getInst().equals(ldInst)) - .flatMap(tlDevice -> tlDevice.getLN0().getDOI().stream()) - .filter(tdoi -> tdoi.getName().equals(doiName)) - .flatMap(tdoi -> tdoi.getSDIOrDAI().stream().map(tUnNaming -> (TDAI)tUnNaming)) - .filter(tdai -> tdai.getName().equals(daiName)) - .findFirst(); + +public static IDataParentAdapter findDoiOrSdi(AbstractLNAdapter lnAdapter, String dataTypeRef) { + if (dataTypeRef.length() < 1) { + Assertions.fail("dataTypeRef must at least contain a DO, but got: " + dataTypeRef); + } + String[] names = dataTypeRef.split("\\."); + IDataParentAdapter parentAdapter = lnAdapter.getDOIAdapterByName(names[0]); + for (int i = 1; i < names.length; i++) { + parentAdapter = parentAdapter.getStructuredDataAdapterByName(names[i]); } + return parentAdapter; +} - public static AbstractDAIAdapter findDai(AbstractLNAdapter lnAdapter, String dataTypeRef) { - String[] names = dataTypeRef.split("\\."); - if (names.length < 2) { - Assertions.fail("dataTypeRef must at least contain a DO and a DA name, but got: " + dataTypeRef); - } +public static Optional findDai(SCL scl, String iedName, String ldInst, String doiName, String daiName) { + return findDai( scl, iedName, ldInst, "LLN0", "", "", doiName, daiName); +} - IDataParentAdapter parentAdapter = findDoiOrSdi(lnAdapter, String.join(".", Arrays.asList(names).subList(0, names.length - 1))); - return parentAdapter.getDataAdapterByName(names[names.length - 1]); - } +public static Optional findDai(SCL scl, String iedName, String ldInst, String lnClass, String lnInst, String lnPrefix, String doiName, String daiName) { + return findAnyLn(scl, iedName, ldInst, lnClass, lnInst, lnPrefix) + .getDOI().stream() + .filter(tdoi -> tdoi.getName().equals(doiName)) + .flatMap(tdoi -> tdoi.getSDIOrDAI().stream().map(tUnNaming -> (TDAI) tUnNaming)) + .filter(tdai -> tdai.getName().equals(daiName)) + .findFirst(); +} - public static String getValue(AbstractDAIAdapter daiAdapter) { - return getValue(daiAdapter.getCurrentElem()); +public static AbstractDAIAdapter findDai(AbstractLNAdapter lnAdapter, String dataTypeRef) { + String[] names = dataTypeRef.split("\\."); + if (names.length < 2) { + Assertions.fail("dataTypeRef must at least contain a DO and a DA name, but got: " + dataTypeRef); } - public static String getValue(TDAI tdai) { - if (!tdai.isSetVal()) { - Assertions.fail("No value found for DAI " + tdai.getName()); - } else if (tdai.getVal().size() > 1) { - Assertions.fail("Expecting a single value for for DAI " + tdai.getName()); - } - return tdai.getVal().get(0).getValue(); - } + IDataParentAdapter parentAdapter = findDoiOrSdi(lnAdapter, String.join(".", Arrays.asList(names).subList(0, names.length - 1))); + return parentAdapter.getDataAdapterByName(names[names.length - 1]); +} +public static String getValue(AbstractDAIAdapter daiAdapter) { + return getValue(daiAdapter.getCurrentElem()); +} - public static LDeviceAdapter findLDeviceByLdName(SCL scl, String ldName) { - return new SclRootAdapter(scl).streamIEDAdapters() - .flatMap(IEDAdapter::streamLDeviceAdapters) - .filter(lDeviceAdapter -> ldName.equals(lDeviceAdapter.getLdName())) - .findFirst() - .orElseThrow(() -> new AssertionFailedError("LDevice with ldName=%s not found in SCD".formatted(ldName))); +public static String getValue(TDAI tdai) { + if (!tdai.isSetVal()) { + Assertions.fail("No value found for DAI " + tdai.getName()); + } else if (tdai.getVal().size() > 1) { + Assertions.fail("Expecting a single value for for DAI " + tdai.getName()); } + return tdai.getVal().get(0).getValue(); +} - public static DataSetAdapter findDataSet(SCL scl, String iedName, String ldInst, String dataSetName) { - LN0Adapter ln0 = findLn0(scl, iedName, ldInst); - return ln0.findDataSetByName(dataSetName) - .orElseThrow(() -> new AssertionFailedError(String.format("DataSet.name=%s not found in IED.name=%s,LDevice.inst=%s,LN0", - dataSetName, iedName, ldInst))); - } - public static T findControlBlock(SCL scl, String iedName, String ldInst, String cbName, Class controlBlockClass) { - LN0Adapter ln0 = findLn0(scl, iedName, ldInst); - return ln0.getTControlsByType(controlBlockClass).stream() - .filter(t -> cbName.equals(t.getName())) - .findFirst() - .orElseThrow(() -> new AssertionFailedError(String.format("%s name=%s not found in IED.name=%s,LDevice.inst=%s,LN0", - controlBlockClass.getSimpleName(), cbName, iedName, ldInst))); - } +public static LDeviceAdapter findLDeviceByLdName(SCL scl, String ldName) { + return new SclRootAdapter(scl).streamIEDAdapters() + .flatMap(IEDAdapter::streamLDeviceAdapters) + .filter(lDeviceAdapter -> ldName.equals(lDeviceAdapter.getLdName())) + .findFirst() + .orElseThrow(() -> new AssertionFailedError("LDevice with ldName=%s not found in SCD".formatted(ldName))); +} - public static void assertControlBlockExists(SCL scd, String iedName, String ldInst, String cbName, - String datSet, String id, ControlBlockEnum controlBlockEnum) { - TControl controlBlock = findControlBlock(scd, iedName, ldInst, cbName, controlBlockEnum.getControlBlockClass()); - assertThat(controlBlock.getDatSet()).isEqualTo(datSet); - assertThat(getControlBlockId(controlBlock)).isEqualTo(id); - } +public static DataSetAdapter findDataSet(SCL scl, String iedName, String ldInst, String dataSetName) { + LN0Adapter ln0 = findLn0(scl, iedName, ldInst); + return ln0.findDataSetByName(dataSetName) + .orElseThrow(() -> new AssertionFailedError(String.format("DataSet.name=%s not found in IED.name=%s,LDevice.inst=%s,LN0", + dataSetName, iedName, ldInst))); +} - private static String getControlBlockId(TControl tControl) { - if (tControl instanceof TGSEControl tgseControl) { - return tgseControl.getAppID(); - } - if (tControl instanceof TSampledValueControl tSampledValueControl) { - return tSampledValueControl.getSmvID(); - } - if (tControl instanceof TReportControl tReportControl) { - return tReportControl.getRptID(); - } - throw new AssertionFailedError("Cannot get Id for ControlBlock of type " + tControl.getClass().getSimpleName()); - } +public static T findControlBlock(SCL scl, String iedName, String ldInst, String cbName, Class controlBlockClass) { + LN0Adapter ln0 = findLn0(scl, iedName, ldInst); + return ln0.getTControlsByType(controlBlockClass).stream() + .filter(t -> cbName.equals(t.getName())) + .findFirst() + .orElseThrow(() -> new AssertionFailedError(String.format("%s name=%s not found in IED.name=%s,LDevice.inst=%s,LN0", + controlBlockClass.getSimpleName(), cbName, iedName, ldInst))); +} - public static Stream streamAllDataSets(SCL scl) { - return streamAllLn0Adapters(scl) - .map(ln0Adapter -> ln0Adapter.getCurrentElem().getDataSet()) - .flatMap(List::stream); - } +public static void assertControlBlockExists(SCL scd, String iedName, String ldInst, String cbName, + String datSet, String id, ControlBlockEnum controlBlockEnum) { + TControl controlBlock = findControlBlock(scd, iedName, ldInst, cbName, controlBlockEnum.getControlBlockClass()); + assertThat(controlBlock.getDatSet()).isEqualTo(datSet); + assertThat(getControlBlockId(controlBlock)).isEqualTo(id); +} - public static Stream streamAllLn0Adapters(SCL scl) { - return new SclRootAdapter(scl) - .streamIEDAdapters() - .flatMap(IEDAdapter::streamLDeviceAdapters) - .filter(LDeviceAdapter::hasLN0) - .map(LDeviceAdapter::getLN0Adapter); +private static String getControlBlockId(TControl tControl) { + if (tControl instanceof TGSEControl tgseControl) { + return tgseControl.getAppID(); } - - public static Stream streamAllExtRef(SCL scl) { - return streamAllLn0Adapters(scl) - .filter(AbstractLNAdapter::hasInputs) - .map(LN0Adapter::getInputsAdapter) - .map(InputsAdapter::getCurrentElem) - .map(TInputs::getExtRef) - .flatMap(List::stream); + if (tControl instanceof TSampledValueControl tSampledValueControl) { + return tSampledValueControl.getSmvID(); } - - public static String getDaiValue(AbstractLNAdapter ln, String doiName, String daiName) { - return ln.getDOIAdapterByName(doiName).getDataAdapterByName(daiName).getCurrentElem().getVal().get(0).getValue(); + if (tControl instanceof TReportControl tReportControl) { + return tReportControl.getRptID(); } + throw new AssertionFailedError("Cannot get Id for ControlBlock of type " + tControl.getClass().getSimpleName()); +} - public static Stream streamAllConnectedApGseP(SCL scd, String pType) { - return scd.getCommunication().getSubNetwork().stream() - .map(TSubNetwork::getConnectedAP) - .flatMap(List::stream) - .map(TConnectedAP::getGSE) - .flatMap(List::stream) - .map(TControlBlock::getAddress) - .map(TAddress::getP) - .flatMap(List::stream) - .filter(tp -> pType.equals(tp.getType())) - .map(TP::getValue); - } +public static Stream streamAllDataSets(SCL scl) { + return streamAllLn0Adapters(scl) + .map(ln0Adapter -> ln0Adapter.getCurrentElem().getDataSet()) + .flatMap(List::stream); +} - public static SclRootAdapter createSclRootAdapterWithIed(String iedName) { - SCL scl = new SCL(); - scl.setHeader(new THeader()); - TIED ied = new TIED(); - ied.setName(iedName); - scl.getIED().add(ied); - return new SclRootAdapter(scl); - } +public static Stream streamAllLn0Adapters(SCL scl) { + return new SclRootAdapter(scl) + .streamIEDAdapters() + .flatMap(IEDAdapter::streamLDeviceAdapters) + .filter(LDeviceAdapter::hasLN0) + .map(LDeviceAdapter::getLN0Adapter); +} - public static SclRootAdapter createSclRootWithConnectedAp(String iedName, String apName) { - SclRootAdapter sclRootAdapter = createSclRootAdapterWithIed(iedName); - SCL scl = sclRootAdapter.getCurrentElem(); - scl.setCommunication(new TCommunication()); - TSubNetwork subNetwork = new TSubNetwork(); - scl.getCommunication().getSubNetwork().add(subNetwork); - subNetwork.getConnectedAP().add(newConnectedAp(iedName, apName)); - return sclRootAdapter; - } +public static Stream streamAllExtRef(SCL scl) { + return streamAllLn0Adapters(scl) + .filter(AbstractLNAdapter::hasInputs) + .map(LN0Adapter::getInputsAdapter) + .map(InputsAdapter::getCurrentElem) + .map(TInputs::getExtRef) + .flatMap(List::stream); +} - public static TExtRef createExtRefExample(String cbName, TServiceType tServiceType) { - TExtRef tExtRef = new TExtRef(); - tExtRef.setIedName("IED_NAME_2"); - tExtRef.setServiceType(tServiceType); - tExtRef.setSrcLDInst("Inst_2"); - tExtRef.setSrcLNInst("LN"); - tExtRef.setSrcPrefix("Prefix"); - tExtRef.setSrcCBName(cbName); - return tExtRef; - } +public static String getDaiValue(AbstractLNAdapter ln, String doiName, String daiName) { + return ln.getDOIAdapterByName(doiName).getDataAdapterByName(daiName).getCurrentElem().getVal().get(0).getValue(); +} - public static SclRootAdapter createIedsInScl(String lnClass, String doName) { - // DataTypeTemplate - TDO tdo = new TDO(); - tdo.setName(doName); - tdo.setType("REF"); - TLNodeType tlNodeType = new TLNodeType(); - tlNodeType.setId("T1"); - tlNodeType.getLnClass().add(lnClass); - tlNodeType.getDO().add(tdo); - - TDA tda = new TDA(); - tda.setName("setSrcRef"); - tda.setValImport(true); - tda.setBType(TPredefinedBasicTypeEnum.OBJ_REF); - tda.setFc(TFCEnum.SP); - - TDOType tdoType = new TDOType(); - tdoType.setId("REF"); - tdoType.getSDOOrDA().add(tda); - - TDataTypeTemplates tDataTypeTemplates = new TDataTypeTemplates(); - tDataTypeTemplates.getLNodeType().add(tlNodeType); - tDataTypeTemplates.getDOType().add(tdoType); - - - //ied Client - TDOI tdoi = new TDOI(); - tdoi.setName(doName); - TLDevice tlDevice = new TLDevice(); - tlDevice.setInst("LD_ADD"); - TInputs tInputs = new TInputs(); - LN0 ln0 = new LN0(); - ln0.setInputs(tInputs); - tlDevice.setLN0(ln0); - - TLDevice tlDevice1 = new TLDevice(); - tlDevice1.setLN0(new LN0()); - tlDevice1.setInst(LD_SUIED); - TLN tln1 = new TLN(); - tln1.getLnClass().add(lnClass); - tln1.setLnType("T1"); - tln1.getDOI().add(tdoi); - tlDevice1.getLN().add(tln1); - TServer tServer1 = new TServer(); - tServer1.getLDevice().add(tlDevice1); - tServer1.getLDevice().add(tlDevice); - TAccessPoint tAccessPoint1 = new TAccessPoint(); - tAccessPoint1.setName("AP_NAME"); - tAccessPoint1.setServer(tServer1); - TIED tied1 = new TIED(); - tied1.setName(IED_NAME_1); - tied1.getAccessPoint().add(tAccessPoint1); - - //ied Source - TLDevice tlDevice2 = new TLDevice(); - tlDevice2.setInst("Inst_2"); - tlDevice2.setLdName("LD_Name"); - tlDevice2.setLN0(new LN0()); - TServer tServer2 = new TServer(); - tServer2.getLDevice().add(tlDevice2); - TAccessPoint tAccessPoint2 = new TAccessPoint(); - tAccessPoint2.setName("AP_NAME"); - tAccessPoint2.setServer(tServer2); - TIED tied2 = new TIED(); - tied2.setName(IED_NAME_2); - tied2.getAccessPoint().add(tAccessPoint2); - //SCL file - SCL scd = new SCL(); - scd.getIED().add(tied1); - scd.getIED().add(tied2); - THeader tHeader = new THeader(); - tHeader.setRevision("1"); - scd.setHeader(tHeader); - scd.setDataTypeTemplates(tDataTypeTemplates); - - return new SclRootAdapter(scd); - } +public static Stream streamAllConnectedApGseP(SCL scd, String pType) { + return scd.getCommunication().getSubNetwork().stream() + .map(TSubNetwork::getConnectedAP) + .flatMap(List::stream) + .map(TConnectedAP::getGSE) + .flatMap(List::stream) + .map(TControlBlock::getAddress) + .map(TAddress::getP) + .flatMap(List::stream) + .filter(tp -> pType.equals(tp.getType())) + .map(TP::getValue); +} - public static List getDaiValues(LDeviceAdapter lDeviceAdapter, String lnClass, String doName, String daName) { - return getDAIAdapters(lDeviceAdapter, lnClass, doName, daName) - .map(daiAdapter -> daiAdapter.getCurrentElem().getVal()) - .flatMap(List::stream) - .toList(); - } +public static SclRootAdapter createSclRootAdapterWithIed(String iedName) { + SCL scl = new SCL(); + scl.setHeader(new THeader()); + TIED ied = new TIED(); + ied.setName(iedName); + scl.getIED().add(ied); + return new SclRootAdapter(scl); +} - public static Stream getDAIAdapters(LDeviceAdapter lDeviceAdapter, String lnClass, String doName, String daName) { - return lDeviceAdapter.getLNAdapters().stream() - .filter(lnAdapter -> lnClassEquals(lnAdapter.getCurrentElem().getLnClass(), lnClass)) - .map(lnAdapter -> lnAdapter.getDOIAdapterByName(doName)) - .map(doiAdapter -> (DOIAdapter.DAIAdapter) doiAdapter.getDataAdapterByName(daName)); - } +public static SclRootAdapter createSclRootWithConnectedAp(String iedName, String apName) { + SclRootAdapter sclRootAdapter = createSclRootAdapterWithIed(iedName); + SCL scl = sclRootAdapter.getCurrentElem(); + scl.setCommunication(new TCommunication()); + TSubNetwork subNetwork = new TSubNetwork(); + scl.getCommunication().getSubNetwork().add(subNetwork); + subNetwork.getConnectedAP().add(newConnectedAp(iedName, apName)); + return sclRootAdapter; +} + +public static TExtRef createExtRefExample(String cbName, TServiceType tServiceType) { + TExtRef tExtRef = new TExtRef(); + tExtRef.setIedName("IED_NAME_2"); + tExtRef.setServiceType(tServiceType); + tExtRef.setSrcLDInst("Inst_2"); + tExtRef.setSrcLNInst("LN"); + tExtRef.setSrcPrefix("Prefix"); + tExtRef.setSrcCBName(cbName); + return tExtRef; +} + +public static SclRootAdapter createIedsInScl(String lnClass, String doName) { + // DataTypeTemplate + TDO tdo = new TDO(); + tdo.setName(doName); + tdo.setType("REF"); + TLNodeType tlNodeType = new TLNodeType(); + tlNodeType.setId("T1"); + tlNodeType.getLnClass().add(lnClass); + tlNodeType.getDO().add(tdo); + + TDA tda = new TDA(); + tda.setName("setSrcRef"); + tda.setValImport(true); + tda.setBType(TPredefinedBasicTypeEnum.OBJ_REF); + tda.setFc(TFCEnum.SP); + + TDOType tdoType = new TDOType(); + tdoType.setId("REF"); + tdoType.getSDOOrDA().add(tda); + + TDataTypeTemplates tDataTypeTemplates = new TDataTypeTemplates(); + tDataTypeTemplates.getLNodeType().add(tlNodeType); + tDataTypeTemplates.getDOType().add(tdoType); + + + //ied Client + TDOI tdoi = new TDOI(); + tdoi.setName(doName); + TLDevice tlDevice = new TLDevice(); + tlDevice.setInst("LD_ADD"); + TInputs tInputs = new TInputs(); + LN0 ln0 = new LN0(); + ln0.setInputs(tInputs); + tlDevice.setLN0(ln0); + + TLDevice tlDevice1 = new TLDevice(); + tlDevice1.setLN0(new LN0()); + tlDevice1.setInst(LD_SUIED); + TLN tln1 = new TLN(); + tln1.getLnClass().add(lnClass); + tln1.setLnType("T1"); + tln1.getDOI().add(tdoi); + tlDevice1.getLN().add(tln1); + TServer tServer1 = new TServer(); + tServer1.getLDevice().add(tlDevice1); + tServer1.getLDevice().add(tlDevice); + TAccessPoint tAccessPoint1 = new TAccessPoint(); + tAccessPoint1.setName("AP_NAME"); + tAccessPoint1.setServer(tServer1); + TIED tied1 = new TIED(); + tied1.setName(IED_NAME_1); + tied1.getAccessPoint().add(tAccessPoint1); + + //ied Source + TLDevice tlDevice2 = new TLDevice(); + tlDevice2.setInst("Inst_2"); + tlDevice2.setLdName("LD_Name"); + tlDevice2.setLN0(new LN0()); + TServer tServer2 = new TServer(); + tServer2.getLDevice().add(tlDevice2); + TAccessPoint tAccessPoint2 = new TAccessPoint(); + tAccessPoint2.setName("AP_NAME"); + tAccessPoint2.setServer(tServer2); + TIED tied2 = new TIED(); + tied2.setName(IED_NAME_2); + tied2.getAccessPoint().add(tAccessPoint2); + //SCL file + SCL scd = new SCL(); + scd.getIED().add(tied1); + scd.getIED().add(tied2); + THeader tHeader = new THeader(); + tHeader.setRevision("1"); + scd.setHeader(tHeader); + scd.setDataTypeTemplates(tDataTypeTemplates); + + return new SclRootAdapter(scd); +} + +public static List getDaiValues(LDeviceAdapter lDeviceAdapter, String lnClass, String doName, String daName) { + return getDAIAdapters(lDeviceAdapter, lnClass, doName, daName) + .map(daiAdapter -> daiAdapter.getCurrentElem().getVal()) + .flatMap(List::stream) + .toList(); +} + +public static Stream getDAIAdapters(LDeviceAdapter lDeviceAdapter, String lnClass, String doName, String daName) { + return lDeviceAdapter.getLNAdapters().stream() + .filter(lnAdapter -> lnClassEquals(lnAdapter.getCurrentElem().getLnClass(), lnClass)) + .map(lnAdapter -> lnAdapter.getDOIAdapterByName(doName)) + .map(doiAdapter -> (DOIAdapter.DAIAdapter) doiAdapter.getDataAdapterByName(daName)); +} } diff --git a/sct-commons/src/test/resources/scl-lnodestatus/lnodestatus.scd b/sct-commons/src/test/resources/scl-lnodestatus/lnodestatus.scd index a982faa69..120833d95 100644 --- a/sct-commons/src/test/resources/scl-lnodestatus/lnodestatus.scd +++ b/sct-commons/src/test/resources/scl-lnodestatus/lnodestatus.scd @@ -27,16 +27,16 @@ - + on - + on - + off - + off @@ -79,21 +79,6 @@ - - - - - - - - - - on;off - - - - - on