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

Add flag to enable/disable static var compensator regulation #3324

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from
Draft
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 @@ -70,7 +70,7 @@ public void updateNetworkSvc(StaticVarCompensator svc, int busNum, boolean vregu
svc.setRegulationMode(StaticVarCompensator.RegulationMode.VOLTAGE);
} else {
if (q == 0) {
svc.setRegulationMode(StaticVarCompensator.RegulationMode.OFF);
svc.setRegulating(false);
} else {
svc.setReactivePowerSetpoint(-q);
svc.setRegulationMode(StaticVarCompensator.RegulationMode.REACTIVE_POWER);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1381,7 +1381,7 @@ public void writeStaticVarCompensatorToFormatter(TableFormatter formatter,
.addCell(vlNum)
.addCell(svc.getBmin() * zb)
.addCell(svc.getBmax() * zb)
.addCell(svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.VOLTAGE))
.addCell(svc.isRegulating() && svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.VOLTAGE))
.addCell(vlSet / vb)
.addCell(svc.getReactivePowerSetpoint())
.addCell(faultNum)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ public void addAdditionalCellsGenerator(TableFormatterHelper formatterHelper, Ge
@Override
public void addAdditionalCellsStaticVarCompensator(TableFormatterHelper formatterHelper,
StaticVarCompensator svc) {
boolean voltageRegulation = svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.VOLTAGE);
boolean voltageRegulation = svc.isRegulating() && svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.VOLTAGE);
int regulatingBusNum = voltageRegulation && svc.getRegulatingTerminal().isConnected() ?
getMapper().getInt(AmplSubset.BUS, svc.getRegulatingTerminal().getBusView().getBus().getId()) : -1;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,6 @@ void writePhaseTapChanger() throws IOException {
@Test
void writeSVC() throws IOException {
Network network = SvcTestCaseFactory.createWithMoreSVCs();

MemDataSource dataSource = new MemDataSource();
export(network, properties, dataSource);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -220,14 +220,15 @@ void testRegulatingBusIdExportGenerators() throws IOException {
@Test
void testRegulatingBusIdExportSvc() throws IOException {
Network network = SvcTestCaseFactory.createWithMoreSVCs();
network.getStaticVarCompensator("SVC2").setRegulationMode(StaticVarCompensator.RegulationMode.OFF);
network.getStaticVarCompensator("SVC2").setRegulating(false);
network.getVoltageLevel("VL1").newStaticVarCompensator()
.setId("SVC1")
.setConnectableBus("B1")
.setBus("B1")
.setBmin(0.0002)
.setBmax(0.0008)
.setRegulationMode(StaticVarCompensator.RegulationMode.VOLTAGE)
.setRegulating(true)
.setVoltageSetpoint(390)
.setRegulatingTerminal(network.getLoad("L2").getTerminal())
.add();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public class RegulatingControlMappingForStaticVarCompensators {
}

public static void initialize(StaticVarCompensatorAdder adder) {
adder.setRegulationMode(StaticVarCompensator.RegulationMode.OFF);
adder.setRegulating(false);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
adder.setRegulating(false);
adder.setRegulating(false);
adder.setRegulationMode(StaticVarCompensator.RegulationMode.VOLTAGE);

shouldn't we set the RegulationMode as VOLTAGE to avoid having a null RegulationMode in those kind of cases?@geofjamg

}

public void add(String iidmId, PropertyBag sm) {
Expand Down Expand Up @@ -121,7 +121,7 @@ private boolean setRegulatingControl(CgmesRegulatingControlForStaticVarCompensat
okSet = true;
} else {
context.fixed("SVCControlMode", () -> String.format("Invalid control mode for static var compensator %s. Regulating control is disabled", svc.getId()));
regulationMode = StaticVarCompensator.RegulationMode.OFF;
regulationMode = null;
Copy link
Contributor

@alicecaron alicecaron Mar 12, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
regulationMode = null;
regulationMode = svc.getRegulationMode();
svc.setRegulating(false);

To be discussed but here we need to avoid having a null RegulationMode + disable the regulation?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe we previously need to check that the svc.getRegulationMode() is not null and if so set it as VOLTAGE to avoid null?

}

svc.setVoltageSetpoint(targetVoltage);
Expand All @@ -130,6 +130,9 @@ private boolean setRegulatingControl(CgmesRegulatingControlForStaticVarCompensat
svc.setRegulationMode(regulationMode);
}
svc.setRegulatingTerminal(regulatingTerminal);
if (regulationMode == null) {
svc.setRegulating(false);
}

return okSet;
}
Expand Down Expand Up @@ -160,21 +163,24 @@ private void setDefaultRegulatingControl(CgmesRegulatingControlForStaticVarCompe
// We try to keep data from original regulating control if available.
// Even if the regulating control was disabled it may have defined a valid target value
if (RegulatingControlMapping.isControlModeVoltage(rc.defaultRegulationMode.toLowerCase())) {
regulationMode = onlyReactivePowerReg ? StaticVarCompensator.RegulationMode.OFF : StaticVarCompensator.RegulationMode.VOLTAGE;
regulationMode = onlyReactivePowerReg ? null : StaticVarCompensator.RegulationMode.VOLTAGE;
targetVoltage = isValidVoltageFromRegulatingControl(control) ? control.targetValue : rc.defaultTargetVoltage;
} else if (isControlModeReactivePower(rc.defaultRegulationMode.toLowerCase())) {
regulationMode = StaticVarCompensator.RegulationMode.REACTIVE_POWER;
targetReactivePower = isValidReactivePowerFromRegulatingControl(control) ? control.targetValue : rc.defaultTargetReactivePower;
} else {
context.fixed("SVCControlMode", () -> String.format("Invalid control mode for static var compensator %s. Regulating control is disabled", svc.getId()));
regulationMode = StaticVarCompensator.RegulationMode.OFF;
regulationMode = null;
}

svc.setVoltageSetpoint(targetVoltage);
svc.setReactivePowerSetpoint(targetReactivePower);
if (rc.controlEnabled) {
svc.setRegulationMode(regulationMode);
}
if (regulationMode == null) {
svc.setRegulating(false);
}
}

// SVCControlMode and voltageSetPoint are optional in Cgmes 3.0
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this comment imply that they are mandatory in CGMES 2.4.15? I will check out of curiosity.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -536,9 +536,9 @@ public static String getGeneratorRegulatingControlMode(Generator generator, Remo
}

public static String getSvcMode(StaticVarCompensator svc) {
if (svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.VOLTAGE)) {
if (svc.getRegulationMode() != null && svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.VOLTAGE)) {
return RegulatingControlEq.REGULATING_CONTROL_VOLTAGE;
} else if (svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.REACTIVE_POWER)) {
} else if (svc.getRegulationMode() != null && svc.getRegulationMode().equals(StaticVarCompensator.RegulationMode.REACTIVE_POWER)) {
return RegulatingControlEq.REGULATING_CONTROL_REACTIVE_POWER;
} else {
boolean validVoltageSetpoint = isValidVoltageSetpoint(svc.getVoltageSetpoint());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,7 @@ private static void addRegulatingControlView(Generator g, Map<String, List<Regul
private static void writeStaticVarCompensators(Network network, String cimNamespace, Map<String, List<RegulatingControlView>> regulatingControlViews,
XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
for (StaticVarCompensator svc : network.getStaticVarCompensators()) {
StaticVarCompensator.RegulationMode regulationMode = svc.getRegulationMode();
boolean controlEnabled = regulationMode != StaticVarCompensator.RegulationMode.OFF;
boolean controlEnabled = svc.isRegulating();

CgmesExportUtil.writeStartAbout("StaticVarCompensator", context.getNamingStrategy().getCgmesId(svc), cimNamespace, writer, context);
writer.writeStartElement(cimNamespace, REGULATING_COND_EQ_CONTROL_ENABLED);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,9 @@ public static void write(String id, String svcName, String equipmentContainer, S
}
writer.writeEndElement();
writer.writeEmptyElement(cimNamespace, EQ_STATICVARCOMPENSATOR_SVCCONTROLMODE);
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, cimNamespace + regulationMode(svcControlMode));
if (svcControlMode != null) {
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, cimNamespace + regulationMode(svcControlMode));
}
writer.writeStartElement(cimNamespace, EQ_STATICVARCOMPENSATOR_VOLTAGESETPOINT);
writer.writeCharacters(CgmesExportUtil.format(voltageSetPoint));
writer.writeEndElement();
Expand All @@ -63,10 +65,6 @@ private static String regulationMode(StaticVarCompensator.RegulationMode svcCont
return "SVCControlMode.voltage";
} else if (StaticVarCompensator.RegulationMode.REACTIVE_POWER.equals(svcControlMode)) {
return "SVCControlMode.reactivePower";
} else if (StaticVarCompensator.RegulationMode.OFF.equals(svcControlMode)) {
// CGMES does not have a "none" value for SVCControlMode enumeration,
// so we have to take a default here
return "SVCControlMode.reactivePower";
}
throw new PowsyblException("Invalid regulation mode for Static Var Compensator " + svcControlMode);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,22 +28,22 @@ void staticVarCompensatorControlTest() {
assertEquals(7, network.getStaticVarCompensatorCount());

StaticVarCompensator svc = network.getStaticVarCompensator("StaticVarCompensator");
assertTrue(checkControl(svc, StaticVarCompensator.RegulationMode.OFF, Double.NaN, Double.NaN));
assertTrue(checkControl(svc, null, Double.NaN, Double.NaN));

svc = network.getStaticVarCompensator("StaticVarCompensator-voltageSetPoint");
assertTrue(checkControl(svc, StaticVarCompensator.RegulationMode.OFF, Double.NaN, Double.NaN));
assertTrue(checkControl(svc, null, Double.NaN, Double.NaN));

svc = network.getStaticVarCompensator("StaticVarCompensator-voltage-svcControlMode");
assertTrue(checkControl(svc, StaticVarCompensator.RegulationMode.OFF, Double.NaN, Double.NaN));
assertTrue(checkControl(svc, null, Double.NaN, Double.NaN));

svc = network.getStaticVarCompensator("StaticVarCompensator-voltageSetPoint-svcControlMode");
assertTrue(checkControl(svc, StaticVarCompensator.RegulationMode.OFF, 405.0, Double.NaN));
assertTrue(checkControl(svc, null, 405.0, Double.NaN));

svc = network.getStaticVarCompensator("StaticVarCompensator-voltageSetPoint-svcControlMode-on");
assertTrue(checkControl(svc, StaticVarCompensator.RegulationMode.VOLTAGE, 405.0, Double.NaN));

svc = network.getStaticVarCompensator("StaticVarCompensator-reactivePower-svcControlMode");
assertTrue(checkControl(svc, StaticVarCompensator.RegulationMode.OFF, Double.NaN, Double.NaN));
assertTrue(checkControl(svc, null, Double.NaN, Double.NaN));

svc = network.getStaticVarCompensator("StaticVarCompensator-reactivePower-svcControlMode-on");
assertTrue(checkControl(svc, StaticVarCompensator.RegulationMode.REACTIVE_POWER, Double.NaN, 10.0));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -556,7 +556,7 @@ void microT4InvalidSvcMode() {
Network modified = new CgmesImport().importData(CgmesConformity1ModifiedCatalog.microT4BeBbInvalidSvcMode().dataSource(), NetworkFactory.findDefault(), importParams);
StaticVarCompensator offSvc = modified.getStaticVarCompensator("3c69652c-ff14-4550-9a87-b6fdaccbb5f4");
assertNotNull(offSvc);
assertEquals(OFF, offSvc.getRegulationMode());
assertFalse(offSvc.isRegulating());
}

@Test
Expand Down Expand Up @@ -586,7 +586,7 @@ void microT4OffSvc() {
Network modified1 = new CgmesImport().importData(CgmesConformity1ModifiedCatalog.microT4BeBbOffSvc().dataSource(), NetworkFactory.findDefault(), importParams);
StaticVarCompensator off1 = modified1.getStaticVarCompensator("3c69652c-ff14-4550-9a87-b6fdaccbb5f4");
assertNotNull(off1);
assertEquals(OFF, off1.getRegulationMode());
assertFalse(off1.isRegulating());

Network modified2 = new CgmesImport().importData(CgmesConformity1ModifiedCatalog.microT4BeBbOffSvcControl().dataSource(), NetworkFactory.findDefault(), importParams);
StaticVarCompensator off2 = modified2.getStaticVarCompensator("3c69652c-ff14-4550-9a87-b6fdaccbb5f4");
Expand All @@ -597,7 +597,7 @@ void microT4OffSvc() {
Network modified3 = new CgmesImport().importData(CgmesConformity1ModifiedCatalog.microT4BeBbOffSvcControlV().dataSource(), NetworkFactory.findDefault(), importParams);
StaticVarCompensator off3 = modified3.getStaticVarCompensator("3c69652c-ff14-4550-9a87-b6fdaccbb5f4");
assertNotNull(off3);
assertEquals(OFF, off3.getRegulationMode());
assertFalse(off3.isRegulating());
assertEquals(231.123, off3.getVoltageSetpoint(), 0.0);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1799,7 +1799,8 @@ private Network prepareNetworkForEQComparison(Network network) {
generator.getTerminal().setP(0.0).setQ(0.0);
} else if (identifiable instanceof StaticVarCompensator) {
StaticVarCompensator staticVarCompensator = (StaticVarCompensator) identifiable;
staticVarCompensator.setRegulationMode(StaticVarCompensator.RegulationMode.OFF).setVoltageSetpoint(0.0);
staticVarCompensator.setRegulationMode(null);
staticVarCompensator.setRegulating(false).setVoltageSetpoint(0.0);
staticVarCompensator.getTerminal().setP(0.0).setQ(0.0);
} else if (identifiable instanceof VscConverterStation) {
VscConverterStation converter = (VscConverterStation) identifiable;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@
import java.nio.file.Path;
import java.util.Properties;

import static com.powsybl.iidm.network.StaticVarCompensator.RegulationMode.OFF;
import static org.junit.jupiter.api.Assertions.*;

/**
Expand All @@ -39,7 +38,8 @@ void microT4SvcRCDisabled() {
Network network = Network.read(CgmesConformity1ModifiedCatalog.microT4BeBbOffSvcControlV().dataSource(), importParams);
StaticVarCompensator svc = network.getStaticVarCompensator(svcId);
assertNotNull(svc);
assertEquals(OFF, svc.getRegulationMode());
assertNull(svc.getRegulationMode());
assertFalse(svc.isRegulating());
assertEquals(rcId, svc.getProperty(Conversion.PROPERTY_REGULATING_CONTROL));
assertEquals(231.123, svc.getVoltageSetpoint(), 0.0);

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/**
* Copyright (c) 2016, RTE (http://www.rte-france.com)
* Copyright (c) 2016-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/.
Expand Down Expand Up @@ -99,8 +99,7 @@ public interface StaticVarCompensator extends Injection<StaticVarCompensator> {

enum RegulationMode {
VOLTAGE,
REACTIVE_POWER,
OFF
REACTIVE_POWER
}

/**
Expand Down Expand Up @@ -178,6 +177,16 @@ enum RegulationMode {
*/
StaticVarCompensator setRegulationMode(RegulationMode regulationMode);

/**
* Get the regulating status.
*/
boolean isRegulating();

/**
* Set the regulating status.
*/
StaticVarCompensator setRegulating(boolean regulating);

/**
* <p>Get the terminal used for regulation.</p>
* @return the terminal used for regulation
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ public interface StaticVarCompensatorAdder extends InjectionAdder<StaticVarCompe

StaticVarCompensatorAdder setRegulationMode(StaticVarCompensator.RegulationMode regulationMode);

StaticVarCompensatorAdder setRegulating(boolean regulating);

default StaticVarCompensatorAdder setRegulatingTerminal(Terminal regulatingTerminal) {
throw new UnsupportedOperationException("Not yet implemented");
}
Expand Down
Loading