From a8bf1b8793f76c5e00927f911ba47059a77076d4 Mon Sep 17 00:00:00 2001 From: massifben <105049157+massifben@users.noreply.github.com> Date: Thu, 8 Aug 2024 11:37:13 +0200 Subject: [PATCH] feat(#414): RSR-1047 - add reportType attribute to HMI controlblock creation Signed-off-by: massifben <105049157+massifben@users.noreply.github.com> --- .../commons/scl/ldevice/LDeviceAdapter.java | 15 +++--- .../xsd/CB_REPORT_SUPERVISION_Config_file.xsd | 3 +- .../compas/sct/commons/HmiServiceTest.java | 51 +++++++++++++++---- 3 files changed, 51 insertions(+), 18 deletions(-) diff --git a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ldevice/LDeviceAdapter.java b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ldevice/LDeviceAdapter.java index 34c14a62f..b12be812f 100644 --- a/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ldevice/LDeviceAdapter.java +++ b/sct-commons/src/main/java/org/lfenergy/compas/sct/commons/scl/ldevice/LDeviceAdapter.java @@ -66,6 +66,7 @@ public class LDeviceAdapter extends SclElementAdapter { private static final long INTG_PD_VALUE_FOR_FC_MX = 2000L; private static final String DA_SETSRCREF = "setSrcRef"; + private static final String CYC_REPORT_TYPE = "CYC"; /** * Constructor @@ -94,19 +95,19 @@ public void createHmiReportControlBlocks(PO po) { findLnAdapter(tfcdaFilter.getLnClass(), tfcdaFilter.getLnInst(), tfcdaFilter.getPrefix()).filter(lnAdapter -> lnAdapter.getDaiModStValValue().map(ActiveStatus::fromValue).map(ActiveStatus.ON::equals).orElse(true))) .map(sourceLn -> sourceLn.getDAI(new DataAttributeRef(toFCDA(tfcdaFilter)), false)) .filter(das -> das.stream().anyMatch(da -> TFCEnum.fromValue(tfcdaFilter.getFc().value()) == da.getFc())) // getDAI does not filter on DA. - .ifPresent(dataAttributeRefs -> createHmiReportCB(ln0, toFCDA(tfcdaFilter)))); + .ifPresent(dataAttributeRefs -> createHmiReportCB(ln0, tfcdaFilter))); } - private void createHmiReportCB(LN0Adapter ln0, TFCDA fcda) { - boolean isFcMx = fcda.getFc() == TFCEnum.MX; - String dataSetSuffix = getInst().toUpperCase(Locale.ENGLISH) + ATTRIBUTE_VALUE_SEPARATOR + (isFcMx ? "CYPO" : "DQPO"); + private void createHmiReportCB(LN0Adapter ln0, TFCDAFilter tfcdaFilter) { + TFCDA fcda = toFCDA(tfcdaFilter); + String dataSetSuffix = getInst().toUpperCase(Locale.ENGLISH) + ATTRIBUTE_VALUE_SEPARATOR + tfcdaFilter.getReportType().substring(0, 2) + "PO"; String dataSetName = DATASET_NAME_PREFIX + dataSetSuffix; DataSetAdapter dataSet = ln0.createDataSetIfNotExists(dataSetName, ControlBlockEnum.REPORT); - dataSet.createFCDAIfNotExists(fcda.getLdInst(), fcda.getPrefix(), fcda.getLnClass().get(0), fcda.getLnInst(), fcda.getDoName(), fcda.getDaName(), fcda.getFc()); + dataSet.createFCDAIfNotExists(fcda.getLdInst(), fcda.getPrefix(), fcda.getLnClass().getFirst(), fcda.getLnInst(), fcda.getDoName(), fcda.getDaName(), fcda.getFc()); String cbName = CONTROLBLOCK_NAME_PREFIX + dataSetSuffix; String cbId = ln0.generateControlBlockId(getLdName(), cbName); ControlBlockAdapter controlBlockAdapter = ln0.createControlBlockIfNotExists(cbName, cbId, dataSetName, ControlBlockEnum.REPORT); - if (isFcMx) { + if (tfcdaFilter.getReportType().equals(CYC_REPORT_TYPE)) { TReportControl tReportControl = (TReportControl) controlBlockAdapter.getCurrentElem(); tReportControl.setIntgPd(INTG_PD_VALUE_FOR_FC_MX); tReportControl.getTrgOps().setDchg(false); @@ -478,7 +479,7 @@ private void updateNewCreatedLnDaiValue(TLN tln, TExtRef tExtRef, String lnInst, private String createVal(TExtRef tExtRef) { String sourceLdName = getParentAdapter().getParentAdapter().getIEDAdapterByName(tExtRef.getIedName()) .getLDeviceAdapterByLdInst(tExtRef.getSrcLDInst()).getLdName(); - String lnClass = !tExtRef.isSetSrcLNClass() ? TLLN0Enum.LLN_0.value() : tExtRef.getSrcLNClass().get(0); + String lnClass = !tExtRef.isSetSrcLNClass() ? TLLN0Enum.LLN_0.value() : tExtRef.getSrcLNClass().getFirst(); return sourceLdName + "/" + lnClass + "." + tExtRef.getSrcCBName(); } diff --git a/sct-commons/src/main/resources/xsd/CB_REPORT_SUPERVISION_Config_file.xsd b/sct-commons/src/main/resources/xsd/CB_REPORT_SUPERVISION_Config_file.xsd index 8f4264086..307fc0f88 100644 --- a/sct-commons/src/main/resources/xsd/CB_REPORT_SUPERVISION_Config_file.xsd +++ b/sct-commons/src/main/resources/xsd/CB_REPORT_SUPERVISION_Config_file.xsd @@ -60,6 +60,7 @@ SPDX-License-Identifier: Apache-2.0 + @@ -69,4 +70,4 @@ SPDX-License-Identifier: Apache-2.0 - \ No newline at end of file + diff --git a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/HmiServiceTest.java b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/HmiServiceTest.java index 1a041bcb4..500065cc4 100644 --- a/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/HmiServiceTest.java +++ b/sct-commons/src/test/java/org/lfenergy/compas/sct/commons/HmiServiceTest.java @@ -27,6 +27,8 @@ @ExtendWith(MockitoExtension.class) class HmiServiceTest { + private static final String DQC_REPORT_TYPE = "DQC"; + private static final String CYC_REPORT_TYPE = "CYC"; @InjectMocks HmiService hmiService; @@ -42,7 +44,7 @@ void setUp() { void createAllIhmReportControlBlocks_with_fc_ST_should_create_dataset_and_controlblock() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-hmi-create-report-cb/scd_create_dataset_and_controlblocks_for_hmi.xml"); - TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST); + TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST, DQC_REPORT_TYPE); po.getFCDAs().getFCDA().add(tfcdaFilter); // When hmiService.createAllHmiReportControlBlocks(scd, po); @@ -69,7 +71,7 @@ void createAllIhmReportControlBlocks_with_fc_ST_should_create_dataset_and_contro void createAllIhmReportControlBlocks_with_fc_MX_should_create_dataset_and_controlblock() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-hmi-create-report-cb/scd_create_dataset_and_controlblocks_for_hmi.xml"); - TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "PVOC", "1", null, "DoName2", Tfc.MX); + TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "PVOC", "1", null, "DoName2", Tfc.MX, CYC_REPORT_TYPE); po.getFCDAs().getFCDA().add(tfcdaFilter); // When hmiService.createAllHmiReportControlBlocks(scd, po); @@ -93,11 +95,39 @@ void createAllIhmReportControlBlocks_with_fc_MX_should_create_dataset_and_contro assertThat(reportControl.getRptEnabled().isSetClientLN()).isFalse(); } + @Test + void createAllIhmReportControlBlocks_with_fc_MX_and_DQC_REPORT_TYPE_should_create_dataset_and_controlblock_with_suffix_DQPO() { + // Given + SCL scd = SclTestMarshaller.getSCLFromFile("/scd-hmi-create-report-cb/scd_create_dataset_and_controlblocks_for_hmi.xml"); + TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "PVOC", "1", null, "DoName2", Tfc.MX, DQC_REPORT_TYPE); + po.getFCDAs().getFCDA().add(tfcdaFilter); + // When + hmiService.createAllHmiReportControlBlocks(scd, po); + // Then + // Check DataSet is created + DataSetAdapter dataSet = findDataSet(scd, "IedName1", "LdInst11", "DS_LDINST11_DQPO"); + assertThat(dataSet.getCurrentElem().getFCDA()).hasSize(1).first() + .usingRecursiveComparison().isEqualTo(toFCDA(tfcdaFilter)); + // Check ControlBlock is created + LN0Adapter ln0 = findLn0(scd, "IedName1", "LdInst11"); + assertThat(ln0.getTControlsByType(TReportControl.class)).hasSize(1); + + TReportControl reportControl = findControlBlock(scd, "IedName1", "LdInst11", "CB_LDINST11_DQPO", TReportControl.class); + assertThat(reportControl).extracting(TReportControl::getRptID, TControl::getDatSet, TReportControl::getConfRev, TReportControl::isBuffered, TReportControl::getBufTime, TReportControl::isIndexed, + TControlWithTriggerOpt::getIntgPd) + .containsExactly("IedName1LdInst11/LLN0.CB_LDINST11_DQPO", "DS_LDINST11_DQPO", 1L, true, 0L, true, 60000L); + assertThat(reportControl.getTrgOps()) + .extracting(TTrgOps::isDchg, TTrgOps::isQchg, TTrgOps::isDupd, TTrgOps::isPeriod, TTrgOps::isGi) + .containsExactly(true, true, false, true, true); + assertThat(reportControl.getRptEnabled().getMax()).isEqualTo(1); + assertThat(reportControl.getRptEnabled().isSetClientLN()).isFalse(); + } + @Test void createAllIhmReportControlBlocks_with_FCDA_on_ln0_should_create_dataset_and_controlblock() { // Given SCL scd = SclTestMarshaller.getSCLFromFile("/scd-hmi-create-report-cb/scd_create_dataset_and_controlblocks_for_hmi.xml"); - TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "LLN0", null, null, "DoName0", Tfc.ST); + TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "LLN0", null, null, "DoName0", Tfc.ST, DQC_REPORT_TYPE); po.getFCDAs().getFCDA().add(tfcdaFilter); // When hmiService.createAllHmiReportControlBlocks(scd, po); @@ -126,7 +156,7 @@ void createAllIhmReportControlBlocks_when_lDevice_ON_but_LN_Mod_StVal_missing_sh SCL scd = SclTestMarshaller.getSCLFromFile("/scd-hmi-create-report-cb/scd_create_dataset_and_controlblocks_for_hmi.xml"); LNAdapter ln = findLn(scd, "IedName1", "LdInst11", "ANCR", "1", null); ln.getCurrentElem().unsetDOI(); - TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST); + TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST, DQC_REPORT_TYPE); po.getFCDAs().getFCDA().add(tfcdaFilter); // When hmiService.createAllHmiReportControlBlocks(scd, po); @@ -151,7 +181,7 @@ void createAllIhmReportControlBlocks_when_lDevice_ON_but_LN_Mod_StVal_OFF_should LNAdapter ln = findLn(scd, "IedName1", "LdInst11", "ANCR", "1", null); ln.getDOIAdapterByName(CommonConstants.MOD_DO_NAME).getDataAdapterByName(CommonConstants.STVAL_DA_NAME).setVal("off"); assertThat(ln.getDaiModStValValue()).hasValue("off"); - TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST); + TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST, DQC_REPORT_TYPE); po.getFCDAs().getFCDA().add(tfcdaFilter); // When hmiService.createAllHmiReportControlBlocks(scd, po); @@ -167,7 +197,7 @@ void createAllIhmReportControlBlocks_when_lDevice_OFF_should_not_create_dataset( LN0Adapter ln0 = findLn0(scd, "IedName1", "LdInst11"); ln0.getDOIAdapterByName(CommonConstants.MOD_DO_NAME).getDataAdapterByName(CommonConstants.STVAL_DA_NAME).setVal("off"); assertThat(findLDevice(scd, "IedName1", "LdInst11").getLDeviceStatus()).hasValue(ActiveStatus.OFF.getValue()); - TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST); + TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST, DQC_REPORT_TYPE); po.getFCDAs().getFCDA().add(tfcdaFilter); // When hmiService.createAllHmiReportControlBlocks(scd, po); @@ -183,7 +213,7 @@ void createAllIhmReportControlBlocks_when_LDevice_has_no_status_should_not_creat LN0Adapter ln0 = findLn0(scd, "IedName1", "LdInst11"); ln0.getDOIAdapterByName(CommonConstants.MOD_DO_NAME).getDataAdapterByName(CommonConstants.STVAL_DA_NAME).getCurrentElem().unsetVal(); assertThat(findLDevice(scd, "IedName1", "LdInst11").getLDeviceStatus()).isEmpty(); - TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST); + TFCDAFilter tfcdaFilter = createFCDAFilter("LdInst11", "ANCR", "1", null, "DoName1", Tfc.ST, DQC_REPORT_TYPE); po.getFCDAs().getFCDA().add(tfcdaFilter); // When hmiService.createAllHmiReportControlBlocks(scd, po); @@ -192,14 +222,15 @@ void createAllIhmReportControlBlocks_when_LDevice_has_no_status_should_not_creat assertThat(streamAllControlBlocks(scd, TReportControl.class)).isEmpty(); } - private static TFCDAFilter createFCDAFilter(String ldInst, String lnClass, String lnInst, String prefix, String doName, Tfc tfc) { + private static TFCDAFilter createFCDAFilter(String ldInst, String lnClass, String lnInst, String prefix, String doName, Tfc tfc, String reportType) { TFCDAFilter tfcdaFilter = new TFCDAFilter(); - tfcdaFilter.setLdInst("LdInst11"); + tfcdaFilter.setLdInst(ldInst); tfcdaFilter.setLnClass(lnClass); - tfcdaFilter.setPrefix(null); + tfcdaFilter.setPrefix(prefix); tfcdaFilter.setDoName(doName); tfcdaFilter.setLnInst(lnInst); tfcdaFilter.setFc(tfc); + tfcdaFilter.setReportType(reportType); return tfcdaFilter; }