Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CGMES. Import StaticVarCompensators: sVCControlMode and voltageSetPoint are deprecated and optional in CGMES 3.0 #3272

Open
wants to merge 5 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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");
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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 <zamarrenolm at aia.es>}
* @author José Antonio Marqués {@literal <marquesja at aia.es>}
*/
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;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
marqueslanauja marked this conversation as resolved.
Show resolved Hide resolved
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) {
marqueslanauja marked this conversation as resolved.
Show resolved Hide resolved
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;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
<rdf:RDF xmlns:cim="http://iec.ch/TC57/CIM100#" xmlns:md="http://iec.ch/TC57/61970-552/ModelDescription/1#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:eu="http://iec.ch/TC57/CIM100-European#">
<md:FullModel rdf:about="urn:uuid:d400c631-75a0-4c30-8aed-832b0d282e73">
<md:Model.created>2024-02-21T11:00:00Z</md:Model.created>
<md:Model.scenarioTime>2024-02-21T11:00:00Z</md:Model.scenarioTime>
<md:Model.version>1</md:Model.version>
<md:Model.description>StaticVarCompensator</md:Model.description>
<md:Model.modelingAuthoritySet>https://www.powsybl.org/</md:Model.modelingAuthoritySet>
<md:Model.profile>http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0</md:Model.profile>
</md:FullModel>

<cim:GeographicalRegion rdf:ID="_GeographicalRegionTest">
<cim:IdentifiedObject.mRID>GeographicalRegionTest</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>GeographicalRegionTest</cim:IdentifiedObject.name>
</cim:GeographicalRegion>
<cim:SubGeographicalRegion rdf:ID="_SubGeographicalRegionTest">
<cim:IdentifiedObject.mRID>SubGeographicalRegionTest</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>SubGeographicalRegionTest</cim:IdentifiedObject.name>
<cim:SubGeographicalRegion.Region rdf:resource="#_GeographicalRegionTest" />
</cim:SubGeographicalRegion>
<cim:Substation rdf:ID="_Substation1">
<cim:IdentifiedObject.mRID>Substation1</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>Substation1</cim:IdentifiedObject.name>
<cim:Substation.Region rdf:resource="#_SubGeographicalRegionTest" />
</cim:Substation>
<cim:BaseVoltage rdf:ID="_BaseVoltage400">
<cim:IdentifiedObject.mRID>BaseVoltage400</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.description>Base Voltage Level 400kV</cim:IdentifiedObject.description>
<cim:IdentifiedObject.name>400.0 kV</cim:IdentifiedObject.name>
<cim:BaseVoltage.nominalVoltage>400.0</cim:BaseVoltage.nominalVoltage>
</cim:BaseVoltage>
<cim:VoltageLevel rdf:ID="_VoltageLevel1">
<cim:IdentifiedObject.mRID>VoltageLevel1</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>VoltageLevel1</cim:IdentifiedObject.name>
<cim:VoltageLevel.highVoltageLimit>420</cim:VoltageLevel.highVoltageLimit>
<cim:VoltageLevel.lowVoltageLimit>380</cim:VoltageLevel.lowVoltageLimit>
<cim:VoltageLevel.Substation rdf:resource="#_Substation1"/>
<cim:VoltageLevel.BaseVoltage rdf:resource="#_BaseVoltage400"/>
</cim:VoltageLevel>
<cim:ConnectivityNode rdf:ID="_ConnectivityNode1">
<cim:IdentifiedObject.mRID>ConnectivityNode1</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>Connectivity Node 1</cim:IdentifiedObject.name>
<cim:ConnectivityNode.ConnectivityNodeContainer rdf:resource="#_VoltageLevel1" />
</cim:ConnectivityNode>

<cim:StaticVarCompensator rdf:ID="_StaticVarCompensator">
<cim:IdentifiedObject.name>StaticVarCompensator</cim:IdentifiedObject.name>
<cim:Equipment.EquipmentContainer rdf:resource="#_VoltageLevel1" />
<cim:StaticVarCompensator.capacitiveRating>5062.5</cim:StaticVarCompensator.capacitiveRating>
<cim:StaticVarCompensator.inductiveRating>-5062.5</cim:StaticVarCompensator.inductiveRating>
<cim:StaticVarCompensator.slope>0.102</cim:StaticVarCompensator.slope>
</cim:StaticVarCompensator>
<cim:Terminal rdf:ID="_StaticVarCompensator_T">
<cim:IdentifiedObject.mRID>StaticVarCompensator_T</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>Terminal</cim:IdentifiedObject.name>
<cim:ACDCTerminal.sequenceNumber>1</cim:ACDCTerminal.sequenceNumber>
<cim:Terminal.phases rdf:resource="http://iec.ch/TC57/CIM100#PhaseCode.ABC" />
<cim:Terminal.ConductingEquipment rdf:resource="#_StaticVarCompensator" />
<cim:Terminal.ConnectivityNode rdf:resource="#_ConnectivityNode1" />
</cim:Terminal>
</rdf:RDF>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
<rdf:RDF xmlns:cim="http://iec.ch/TC57/CIM100#" xmlns:md="http://iec.ch/TC57/61970-552/ModelDescription/1#" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:eu="http://iec.ch/TC57/CIM100-European#">
<md:FullModel rdf:about="urn:uuid:d400c631-75a0-4c30-8aed-832b0d282e73">
<md:Model.created>2024-02-21T11:00:00Z</md:Model.created>
<md:Model.scenarioTime>2024-02-21T11:00:00Z</md:Model.scenarioTime>
<md:Model.version>1</md:Model.version>
<md:Model.description>StaticVarCompensator</md:Model.description>
<md:Model.modelingAuthoritySet>https://www.powsybl.org/</md:Model.modelingAuthoritySet>
<md:Model.profile>http://iec.ch/TC57/ns/CIM/CoreEquipment-EU/3.0</md:Model.profile>
</md:FullModel>

<cim:GeographicalRegion rdf:ID="_GeographicalRegionTest">
<cim:IdentifiedObject.mRID>GeographicalRegionTest</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>GeographicalRegionTest</cim:IdentifiedObject.name>
</cim:GeographicalRegion>
<cim:SubGeographicalRegion rdf:ID="_SubGeographicalRegionTest">
<cim:IdentifiedObject.mRID>SubGeographicalRegionTest</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>SubGeographicalRegionTest</cim:IdentifiedObject.name>
<cim:SubGeographicalRegion.Region rdf:resource="#_GeographicalRegionTest" />
</cim:SubGeographicalRegion>
<cim:Substation rdf:ID="_Substation1">
<cim:IdentifiedObject.mRID>Substation1</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>Substation1</cim:IdentifiedObject.name>
<cim:Substation.Region rdf:resource="#_SubGeographicalRegionTest" />
</cim:Substation>
<cim:BaseVoltage rdf:ID="_BaseVoltage400">
<cim:IdentifiedObject.mRID>BaseVoltage400</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.description>Base Voltage Level 400kV</cim:IdentifiedObject.description>
<cim:IdentifiedObject.name>400.0 kV</cim:IdentifiedObject.name>
<cim:BaseVoltage.nominalVoltage>400.0</cim:BaseVoltage.nominalVoltage>
</cim:BaseVoltage>
<cim:VoltageLevel rdf:ID="_VoltageLevel1">
<cim:IdentifiedObject.mRID>VoltageLevel1</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>VoltageLevel1</cim:IdentifiedObject.name>
<cim:VoltageLevel.highVoltageLimit>420</cim:VoltageLevel.highVoltageLimit>
<cim:VoltageLevel.lowVoltageLimit>380</cim:VoltageLevel.lowVoltageLimit>
<cim:VoltageLevel.Substation rdf:resource="#_Substation1"/>
<cim:VoltageLevel.BaseVoltage rdf:resource="#_BaseVoltage400"/>
</cim:VoltageLevel>
<cim:ConnectivityNode rdf:ID="_ConnectivityNode1">
<cim:IdentifiedObject.mRID>ConnectivityNode1</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>Connectivity Node 1</cim:IdentifiedObject.name>
<cim:ConnectivityNode.ConnectivityNodeContainer rdf:resource="#_VoltageLevel1" />
</cim:ConnectivityNode>

<cim:StaticVarCompensator rdf:ID="_StaticVarCompensator">
<cim:IdentifiedObject.name>StaticVarCompensator</cim:IdentifiedObject.name>
<cim:Equipment.EquipmentContainer rdf:resource="#_VoltageLevel1" />
<cim:StaticVarCompensator.capacitiveRating>5062.5</cim:StaticVarCompensator.capacitiveRating>
<cim:StaticVarCompensator.inductiveRating>-5062.5</cim:StaticVarCompensator.inductiveRating>
<cim:StaticVarCompensator.slope>0.102</cim:StaticVarCompensator.slope>
<cim:StaticVarCompensator.sVCControlMode rdf:resource="http://iec.ch/TC57/CIM100#SVCControlMode.reactivePower"/>
</cim:StaticVarCompensator>
<cim:Terminal rdf:ID="_StaticVarCompensator_T">
<cim:IdentifiedObject.mRID>StaticVarCompensator_T</cim:IdentifiedObject.mRID>
<cim:IdentifiedObject.name>Terminal</cim:IdentifiedObject.name>
<cim:ACDCTerminal.sequenceNumber>1</cim:ACDCTerminal.sequenceNumber>
<cim:Terminal.phases rdf:resource="http://iec.ch/TC57/CIM100#PhaseCode.ABC" />
<cim:Terminal.ConductingEquipment rdf:resource="#_StaticVarCompensator" />
<cim:Terminal.ConnectivityNode rdf:resource="#_ConnectivityNode1" />
</cim:Terminal>
</rdf:RDF>
Loading
Loading