diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/RegulatingControlMappingForStaticVarCompensators.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/RegulatingControlMappingForStaticVarCompensators.java index a5dba5a75b6..18f3bcda0d6 100644 --- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/RegulatingControlMappingForStaticVarCompensators.java +++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/RegulatingControlMappingForStaticVarCompensators.java @@ -148,6 +148,9 @@ private boolean isValidReactivePowerFromRegulatingControl(RegulatingControl cont } private void setDefaultRegulatingControl(CgmesRegulatingControlForStaticVarCompensator rc, StaticVarCompensator svc, boolean onlyReactivePowerReg, RegulatingControl control) { + if (!defaultRegulatingControlIsWellDefined(rc)) { + return; + } double targetVoltage = Double.NaN; double targetReactivePower = Double.NaN; @@ -174,6 +177,13 @@ private void setDefaultRegulatingControl(CgmesRegulatingControlForStaticVarCompe } } + // SVCControlMode and voltageSetPoint are optional in Cgmes 3.0 + private static boolean defaultRegulatingControlIsWellDefined(CgmesRegulatingControlForStaticVarCompensator rc) { + return rc.defaultRegulationMode != null + && (RegulatingControlMapping.isControlModeVoltage(rc.defaultRegulationMode.toLowerCase()) && rc.defaultTargetVoltage > 0.0 + || isControlModeReactivePower(rc.defaultRegulationMode.toLowerCase()) && Double.isFinite(rc.defaultTargetReactivePower)); + } + private static boolean isControlModeReactivePower(String controlMode) { return controlMode != null && controlMode.endsWith("reactivepower"); } diff --git a/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/StaticVarCompensatorTest.java b/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/StaticVarCompensatorTest.java new file mode 100644 index 00000000000..65e89a0ab2f --- /dev/null +++ b/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/StaticVarCompensatorTest.java @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2025, RTE (http://www.rte-france.com) + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * SPDX-License-Identifier: MPL-2.0 + */ +package com.powsybl.cgmes.conversion.test; + +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.StaticVarCompensator; +import org.junit.jupiter.api.Test; + +import static com.powsybl.cgmes.conversion.test.ConversionUtil.readCgmesResources; +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Luma Zamarreño {@literal } + * @author José Antonio Marqués {@literal } + */ +class StaticVarCompensatorTest { + + private static final String DIR = "/staticVarCompensator/"; + + @Test + void importEqTest() { + assertTrue(importEqFileAndVerifyThatTheControlIsOff("staticVarCompensator_EQ.xml")); + } + + @Test + void importEqWithVoltageSetpointTest() { + assertTrue(importEqFileAndVerifyThatTheControlIsOff("staticVarCompensator_EQ_voltageSetpoint.xml")); + } + + @Test + void importEqWithVoltageSvcControlModeTest() { + assertTrue(importEqFileAndVerifyThatTheControlIsOff("staticVarCompensator_EQ_V_svcControlMode.xml")); + } + + @Test + void importEqWithVoltageSvcControlModeAndVoltageSetpointTest() { + Network network = readCgmesResources(DIR, "staticVarCompensator_EQ_V_svcControlMode_voltageSetpoint.xml", "staticVarCompensator_SSH.xml"); + assertEquals(1, network.getStaticVarCompensatorCount()); + + StaticVarCompensator staticVarCompensator = network.getStaticVarCompensator("StaticVarCompensator"); + assertTrue(checkControl(staticVarCompensator, StaticVarCompensator.RegulationMode.VOLTAGE, 405.0, Double.NaN)); + } + + @Test + void importEqAndSshTest() { + Network network = readCgmesResources(DIR, "staticVarCompensator_EQ.xml", "staticVarCompensator_SSH.xml"); + assertEquals(1, network.getStaticVarCompensatorCount()); + + StaticVarCompensator staticVarCompensator = network.getStaticVarCompensator("StaticVarCompensator"); + assertTrue(checkControl(staticVarCompensator, StaticVarCompensator.RegulationMode.OFF, Double.NaN, Double.NaN)); + } + + @Test + void importEqWithReactivePowerSvcControlModeTest() { + assertTrue(importEqFileAndVerifyThatTheControlIsOff("staticVarCompensator_EQ_Q_svcControlMode.xml")); + } + + @Test + void importEqWithReactivePowerSvcControlModeAndSshTest() { + Network network = readCgmesResources(DIR, "staticVarCompensator_EQ_Q_svcControlMode.xml", "staticVarCompensator_SSH.xml"); + assertEquals(1, network.getStaticVarCompensatorCount()); + + StaticVarCompensator staticVarCompensator = network.getStaticVarCompensator("StaticVarCompensator"); + assertTrue(checkControl(staticVarCompensator, StaticVarCompensator.RegulationMode.REACTIVE_POWER, Double.NaN, 10.0)); + } + + private static boolean importEqFileAndVerifyThatTheControlIsOff(String eqFile) { + Network network = readCgmesResources(DIR, eqFile); + assertEquals(1, network.getStaticVarCompensatorCount()); + + StaticVarCompensator staticVarCompensator = network.getStaticVarCompensator("StaticVarCompensator"); + assertTrue(checkControl(staticVarCompensator, StaticVarCompensator.RegulationMode.OFF, Double.NaN, Double.NaN)); + return true; + } + + private static boolean checkControl(StaticVarCompensator staticVarCompensator, StaticVarCompensator.RegulationMode defaultRegulationMode, double defaultTargetV, double defaultTargetQ) { + assertNotNull(staticVarCompensator); + assertNotNull(staticVarCompensator.getRegulatingTerminal()); + double tol = 0.0000001; + assertEquals(defaultTargetV, staticVarCompensator.getVoltageSetpoint(), tol); + assertEquals(defaultTargetQ, staticVarCompensator.getReactivePowerSetpoint(), tol); + assertEquals(defaultRegulationMode, staticVarCompensator.getRegulationMode()); + return true; + } +} diff --git a/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/export/ExportXmlCompare.java b/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/export/ExportXmlCompare.java index dca16ba77ba..46d60378d8e 100644 --- a/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/export/ExportXmlCompare.java +++ b/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/export/ExportXmlCompare.java @@ -604,18 +604,33 @@ static ComparisonResult ignoringRdfChildLookupEquivalentInjection(Comparison com return result; } - static ComparisonResult ignoringRdfChildLookupStaticVarCompensator(Comparison comparison, ComparisonResult result) { - if (result == ComparisonResult.DIFFERENT && comparison.getType() == ComparisonType.CHILD_LOOKUP) { + static ComparisonResult ignoringStaticVarCompensatorControlEnabled(Comparison comparison, ComparisonResult result) { + if (result == ComparisonResult.DIFFERENT && comparison.getType() == ComparisonType.TEXT_VALUE) { String cxpath = comparison.getControlDetails().getXPath(); - if (cxpath != null && cxpath.contains("RDF") && cxpath.contains("StaticVarCompensator")) { + if (cxpath != null && cxpath.contains("StaticVarCompensator") && cxpath.contains(".controlEnabled")) { return ComparisonResult.EQUAL; } } return result; } - static ComparisonResult ignoringRdfChildLookupRegulatingControl(Comparison comparison, ComparisonResult result) { - if (result == ComparisonResult.DIFFERENT && comparison.getType() == ComparisonType.CHILD_LOOKUP) { + static ComparisonResult ignoringStaticVarCompensatorQ(Comparison comparison, ComparisonResult result) { + if (result == ComparisonResult.DIFFERENT && comparison.getType() == ComparisonType.TEXT_VALUE) { + String cxpath = comparison.getControlDetails().getXPath(); + if (cxpath != null && cxpath.contains("StaticVarCompensator.q")) { + return ComparisonResult.EQUAL; + } + } + return result; + } + + static ComparisonResult ignoringRegulatingControl(Comparison comparison, ComparisonResult result) { + if (result == ComparisonResult.DIFFERENT && comparison.getType() == ComparisonType.TEXT_VALUE) { + String cxpath = comparison.getControlDetails().getXPath(); + if (cxpath != null && cxpath.contains("RDF") && cxpath.contains("RegulatingControl")) { + return ComparisonResult.EQUAL; + } + } else if (result == ComparisonResult.DIFFERENT && comparison.getType() == ComparisonType.CHILD_LOOKUP) { String cxpath = comparison.getControlDetails().getXPath(); if (cxpath != null && cxpath.contains("RDF") && cxpath.contains("RegulatingControl")) { return ComparisonResult.EQUAL; diff --git a/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/export/SteadyStateHypothesisExportTest.java b/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/export/SteadyStateHypothesisExportTest.java index 43102c5c030..057af0834fe 100644 --- a/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/export/SteadyStateHypothesisExportTest.java +++ b/cgmes/cgmes-conversion/src/test/java/com/powsybl/cgmes/conversion/test/export/SteadyStateHypothesisExportTest.java @@ -354,8 +354,9 @@ void microGridCgmesExportPreservingOriginalClassesOfLoads() throws IOException, ExportXmlCompare::ignoringTextValueTapChangerControlEnabled, ExportXmlCompare::ignoringRdfChildLookupTerminal, ExportXmlCompare::ignoringRdfChildLookupEquivalentInjection, - ExportXmlCompare::ignoringRdfChildLookupStaticVarCompensator, - ExportXmlCompare::ignoringRdfChildLookupRegulatingControl, + ExportXmlCompare::ignoringStaticVarCompensatorControlEnabled, + ExportXmlCompare::ignoringStaticVarCompensatorQ, + ExportXmlCompare::ignoringRegulatingControl, ExportXmlCompare::ignoringTextValueEquivalentInjection); assertTrue(ExportXmlCompare.compareSSH(expectedSsh, new ByteArrayInputStream(actualSsh.getBytes(StandardCharsets.UTF_8)), knownDiffsSsh)); } diff --git a/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ.xml b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ.xml new file mode 100644 index 00000000000..e20720f4a62 --- /dev/null +++ b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ.xml @@ -0,0 +1,60 @@ + + + 2024-02-21T11:00:00Z + 2024-02-21T11:00:00Z + 1 + StaticVarCompensator + https://www.powsybl.org/ + http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0 + + + + GeographicalRegionTest + GeographicalRegionTest + + + SubGeographicalRegionTest + SubGeographicalRegionTest + + + + Substation1 + Substation1 + + + + BaseVoltage400 + Base Voltage Level 400kV + 400.0 kV + 400.0 + + + VoltageLevel1 + VoltageLevel1 + 420 + 380 + + + + + ConnectivityNode1 + Connectivity Node 1 + + + + + StaticVarCompensator + + 5062.5 + -5062.5 + 0.102 + + + StaticVarCompensator_T + Terminal + 1 + + + + + diff --git a/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_Q_svcControlMode.xml b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_Q_svcControlMode.xml new file mode 100644 index 00000000000..9a3610d3145 --- /dev/null +++ b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_Q_svcControlMode.xml @@ -0,0 +1,61 @@ + + + 2024-02-21T11:00:00Z + 2024-02-21T11:00:00Z + 1 + StaticVarCompensator + https://www.powsybl.org/ + http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0 + + + + GeographicalRegionTest + GeographicalRegionTest + + + SubGeographicalRegionTest + SubGeographicalRegionTest + + + + Substation1 + Substation1 + + + + BaseVoltage400 + Base Voltage Level 400kV + 400.0 kV + 400.0 + + + VoltageLevel1 + VoltageLevel1 + 420 + 380 + + + + + ConnectivityNode1 + Connectivity Node 1 + + + + + StaticVarCompensator + + 5062.5 + -5062.5 + 0.102 + + + + StaticVarCompensator_T + Terminal + 1 + + + + + diff --git a/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_V_svcControlMode.xml b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_V_svcControlMode.xml new file mode 100644 index 00000000000..87052959cf4 --- /dev/null +++ b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_V_svcControlMode.xml @@ -0,0 +1,61 @@ + + + 2024-02-21T11:00:00Z + 2024-02-21T11:00:00Z + 1 + StaticVarCompensator + https://www.powsybl.org/ + http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0 + + + + GeographicalRegionTest + GeographicalRegionTest + + + SubGeographicalRegionTest + SubGeographicalRegionTest + + + + Substation1 + Substation1 + + + + BaseVoltage400 + Base Voltage Level 400kV + 400.0 kV + 400.0 + + + VoltageLevel1 + VoltageLevel1 + 420 + 380 + + + + + ConnectivityNode1 + Connectivity Node 1 + + + + + StaticVarCompensator + + 5062.5 + -5062.5 + 0.102 + + + + StaticVarCompensator_T + Terminal + 1 + + + + + diff --git a/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_V_svcControlMode_voltageSetpoint.xml b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_V_svcControlMode_voltageSetpoint.xml new file mode 100644 index 00000000000..076fa47f589 --- /dev/null +++ b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_V_svcControlMode_voltageSetpoint.xml @@ -0,0 +1,62 @@ + + + 2024-02-21T11:00:00Z + 2024-02-21T11:00:00Z + 1 + StaticVarCompensator + https://www.powsybl.org/ + http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0 + + + + GeographicalRegionTest + GeographicalRegionTest + + + SubGeographicalRegionTest + SubGeographicalRegionTest + + + + Substation1 + Substation1 + + + + BaseVoltage400 + Base Voltage Level 400kV + 400.0 kV + 400.0 + + + VoltageLevel1 + VoltageLevel1 + 420 + 380 + + + + + ConnectivityNode1 + Connectivity Node 1 + + + + + StaticVarCompensator + + 5062.5 + -5062.5 + 0.102 + + 405.0 + + + StaticVarCompensator_T + Terminal + 1 + + + + + diff --git a/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_voltageSetpoint.xml b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_voltageSetpoint.xml new file mode 100644 index 00000000000..f48bf477aaf --- /dev/null +++ b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_EQ_voltageSetpoint.xml @@ -0,0 +1,61 @@ + + + 2024-02-21T11:00:00Z + 2024-02-21T11:00:00Z + 1 + StaticVarCompensator + https://www.powsybl.org/ + http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0 + + + + GeographicalRegionTest + GeographicalRegionTest + + + SubGeographicalRegionTest + SubGeographicalRegionTest + + + + Substation1 + Substation1 + + + + BaseVoltage400 + Base Voltage Level 400kV + 400.0 kV + 400.0 + + + VoltageLevel1 + VoltageLevel1 + 420 + 380 + + + + + ConnectivityNode1 + Connectivity Node 1 + + + + + StaticVarCompensator + + 5062.5 + -5062.5 + 0.102 + 405.0 + + + StaticVarCompensator_T + Terminal + 1 + + + + + diff --git a/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_SSH.xml b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_SSH.xml new file mode 100644 index 00000000000..0c33ae3a8ca --- /dev/null +++ b/cgmes/cgmes-conversion/src/test/resources/staticVarCompensator/staticVarCompensator_SSH.xml @@ -0,0 +1,19 @@ + + + 2024-02-21T11:00:00Z + 2024-02-21T11:00:00Z + 1 + StaticVarCompensator + https://www.powsybl.org/ + http://iec.ch/TC57/ns/CIM/SteadyStateHypothesis-EU/3.0 + + + + true + true + 10.0 + + + true + + diff --git a/cgmes/cgmes-model/src/main/resources/CIM100.sparql b/cgmes/cgmes-model/src/main/resources/CIM100.sparql index ba668498e7a..148333c0f98 100644 --- a/cgmes/cgmes-model/src/main/resources/CIM100.sparql +++ b/cgmes/cgmes-model/src/main/resources/CIM100.sparql @@ -109,6 +109,29 @@ OPTIONAL { GRAPH ?graphSSH2 { }} } +# query: staticVarCompensators +SELECT * +WHERE { +{ GRAPH ?graph { + ?StaticVarCompensator + a cim:StaticVarCompensator ; + cim:IdentifiedObject.name ?name ; + cim:StaticVarCompensator.capacitiveRating ?capacitiveRating ; + cim:StaticVarCompensator.inductiveRating ?inductiveRating ; + cim:StaticVarCompensator.slope ?slope . + ?Terminal cim:Terminal.ConductingEquipment ?StaticVarCompensator . + + OPTIONAL { ?StaticVarCompensator cim:StaticVarCompensator.sVCControlMode ?controlMode } + OPTIONAL { ?StaticVarCompensator cim:StaticVarCompensator.voltageSetPoint ?voltageSetPoint } + OPTIONAL { ?StaticVarCompensator cim:RegulatingCondEq.RegulatingControl ?RegulatingControl } +}} +OPTIONAL { GRAPH ?graphSSH { + ?StaticVarCompensator + cim:StaticVarCompensator.q ?q ; + cim:RegulatingCondEq.controlEnabled ?controlEnabled +}} +} + # query: operationalLimits SELECT * WHERE {