diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/AbstractRegulatingEquipment.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/AbstractRegulatingEquipment.java index 5354dcd4e..a08cc5af3 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/AbstractRegulatingEquipment.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/AbstractRegulatingEquipment.java @@ -43,4 +43,11 @@ public Terminal getRegulatingTerminal() { return regulatingPoint.getRegulatingTerminal(); } + public Boolean isRegulating() { + return regulatingPoint.isRegulating(); + } + + public void setRegulating(boolean regulating) { + regulatingPoint.setRegulating(regulating); + } } diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/GeneratorAdderImpl.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/GeneratorAdderImpl.java index 6853020c7..316de009e 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/GeneratorAdderImpl.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/GeneratorAdderImpl.java @@ -131,7 +131,7 @@ public Generator add() { TerminalRefAttributes terminalRefAttributes = TerminalRefUtils.getTerminalRefAttributes(regulatingTerminal); RegulatingPointAttributes regulatingPointAttributes = new RegulatingPointAttributes(getId(), ResourceType.GENERATOR, - new TerminalRefAttributes(getId(), null), terminalRefAttributes, null, ResourceType.GENERATOR); + new TerminalRefAttributes(getId(), null), terminalRefAttributes, null, ResourceType.GENERATOR, voltageRegulatorOn); Resource resource = Resource.generatorBuilder() .id(id) @@ -146,7 +146,6 @@ public Generator add() { .energySource(energySource) .maxP(maxP) .minP(minP) - .voltageRegulatorOn(voltageRegulatorOn) .targetP(targetP) .targetQ(targetQ) .targetV(targetV) diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/GeneratorImpl.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/GeneratorImpl.java index 60a0e13ee..d8da2c82d 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/GeneratorImpl.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/GeneratorImpl.java @@ -106,15 +106,15 @@ public void remove() { @Override public boolean isVoltageRegulatorOn() { - return getResource().getAttributes().isVoltageRegulatorOn(); + return this.isRegulating(); } @Override public Generator setVoltageRegulatorOn(boolean voltageRegulatorOn) { ValidationUtil.checkVoltageControl(this, voltageRegulatorOn, getTargetV(), getTargetQ(), ValidationLevel.STEADY_STATE_HYPOTHESIS, getNetwork().getReportNodeContext().getReportNode()); - boolean oldValue = getResource().getAttributes().isVoltageRegulatorOn(); + boolean oldValue = this.isRegulating(); if (voltageRegulatorOn != oldValue) { - updateResource(res -> res.getAttributes().setVoltageRegulatorOn(voltageRegulatorOn)); + this.setRegulating(voltageRegulatorOn); String variantId = index.getNetwork().getVariantManager().getWorkingVariantId(); index.notifyUpdate(this, "voltageRegulatorOn", variantId, oldValue, voltageRegulatorOn); } diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/RegulatingPoint.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/RegulatingPoint.java index a515ec8c1..2f0890a64 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/RegulatingPoint.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/RegulatingPoint.java @@ -102,7 +102,10 @@ private void resetRegulationMode(Terminal regulatingTerminal, Terminal localTerm } default -> throw new PowsyblException("No regulation for this kind of equipment"); } + // the target can be inappropriated if it was a remote regulation + setRegulating(false); } + // if the regulating equipment was already regulating on his bus we reallocate the regulating point and we keep the regulation on } void remove() { @@ -117,4 +120,12 @@ public String getRegulatingEquipmentId() { public ResourceType getRegulatingEquipmentType() { return getAttributes().getRegulatingResourceType(); } + + public Boolean isRegulating() { + return getAttributes().getRegulating(); + } + + public void setRegulating(boolean regulating) { + identifiable.updateResource(res -> getAttributes(res).setRegulating(regulating)); + } } diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/ShuntCompensatorAdderImpl.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/ShuntCompensatorAdderImpl.java index 75675445a..1dd7739cb 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/ShuntCompensatorAdderImpl.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/ShuntCompensatorAdderImpl.java @@ -210,7 +210,7 @@ public ShuntCompensator add() { ValidationUtil.checkVoltageControl(this, voltageRegulatorOn, targetV, ValidationLevel.STEADY_STATE_HYPOTHESIS, getNetwork().getReportNodeContext().getReportNode()); ValidationUtil.checkTargetDeadband(this, "shunt compensator", voltageRegulatorOn, targetDeadband, ValidationLevel.STEADY_STATE_HYPOTHESIS, getNetwork().getReportNodeContext().getReportNode()); RegulatingPointAttributes regulatingPointAttributes = new RegulatingPointAttributes(getId(), ResourceType.SHUNT_COMPENSATOR, - new TerminalRefAttributes(getId(), null), terminalRefAttributes, null, ResourceType.SHUNT_COMPENSATOR); + new TerminalRefAttributes(getId(), null), terminalRefAttributes, null, ResourceType.SHUNT_COMPENSATOR, voltageRegulatorOn); Resource resource = Resource.shuntCompensatorBuilder() .id(id) @@ -225,7 +225,6 @@ public ShuntCompensator add() { .sectionCount(sectionCount) .model(model) .regulatingPoint(regulatingPointAttributes) - .voltageRegulatorOn(voltageRegulatorOn) .targetV(targetV) .targetDeadband(targetDeadband) .build()) diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/ShuntCompensatorImpl.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/ShuntCompensatorImpl.java index 287c81d82..76866d022 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/ShuntCompensatorImpl.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/ShuntCompensatorImpl.java @@ -117,16 +117,16 @@ public M getModel(Class type) { @Override public boolean isVoltageRegulatorOn() { - return getResource().getAttributes().isVoltageRegulatorOn(); + return this.isRegulating(); } @Override public ShuntCompensator setVoltageRegulatorOn(boolean voltageRegulatorOn) { ValidationUtil.checkVoltageControl(this, voltageRegulatorOn, getTargetV(), ValidationLevel.STEADY_STATE_HYPOTHESIS, getNetwork().getReportNodeContext().getReportNode()); ValidationUtil.checkTargetDeadband(this, "shunt compensator", voltageRegulatorOn, getTargetDeadband(), ValidationLevel.STEADY_STATE_HYPOTHESIS, getNetwork().getReportNodeContext().getReportNode()); - boolean oldValue = getResource().getAttributes().isVoltageRegulatorOn(); + boolean oldValue = this.isRegulating(); if (voltageRegulatorOn != oldValue) { - updateResource(res -> res.getAttributes().setVoltageRegulatorOn(voltageRegulatorOn)); + this.setRegulating(voltageRegulatorOn); String variantId = index.getNetwork().getVariantManager().getWorkingVariantId(); index.notifyUpdate(this, "voltageRegulatorOn", variantId, oldValue, voltageRegulatorOn); } diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/StaticVarCompensatorAdderImpl.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/StaticVarCompensatorAdderImpl.java index bf679a278..178079701 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/StaticVarCompensatorAdderImpl.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/StaticVarCompensatorAdderImpl.java @@ -76,8 +76,9 @@ public StaticVarCompensator add() { ValidationUtil.checkRegulatingTerminal(this, regulatingTerminal, getNetwork()); TerminalRefAttributes terminalRefAttributes = TerminalRefUtils.getTerminalRefAttributes(regulatingTerminal); + Boolean isRegulating = regulationMode == StaticVarCompensator.RegulationMode.VOLTAGE; RegulatingPointAttributes regulatingPointAttributes = new RegulatingPointAttributes(getId(), ResourceType.STATIC_VAR_COMPENSATOR, - new TerminalRefAttributes(getId(), null), terminalRefAttributes, String.valueOf(regulationMode), ResourceType.STATIC_VAR_COMPENSATOR); + new TerminalRefAttributes(getId(), null), terminalRefAttributes, String.valueOf(regulationMode), ResourceType.STATIC_VAR_COMPENSATOR, isRegulating); Resource resource = Resource.staticVarCompensatorBuilder() .id(id) .variantNum(index.getWorkingVariantNum()) diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/VscConverterStationAdderImpl.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/VscConverterStationAdderImpl.java index f5ec18586..1860e6d07 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/VscConverterStationAdderImpl.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/VscConverterStationAdderImpl.java @@ -58,7 +58,7 @@ public VscConverterStation add() { TerminalRefAttributes terminalRefAttributes = TerminalRefUtils.getTerminalRefAttributes(regulatingTerminal); RegulatingPointAttributes regulatingPointAttributes = new RegulatingPointAttributes(getId(), ResourceType.VSC_CONVERTER_STATION, - new TerminalRefAttributes(getId(), null), terminalRefAttributes, null, ResourceType.VSC_CONVERTER_STATION); + new TerminalRefAttributes(getId(), null), terminalRefAttributes, null, ResourceType.VSC_CONVERTER_STATION, voltageRegulatorOn); Resource resource = Resource.vscConverterStationBuilder() .id(id) @@ -71,7 +71,6 @@ public VscConverterStation add() { .bus(getBus()) .connectableBus(getConnectableBus() != null ? getConnectableBus() : getBus()) .lossFactor(getLossFactor()) - .voltageRegulatorOn(voltageRegulatorOn) .voltageSetPoint(voltageSetPoint) .reactivePowerSetPoint(reactivePowerSetPoint) .regulatingPoint(regulatingPointAttributes) diff --git a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/VscConverterStationImpl.java b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/VscConverterStationImpl.java index 798211695..1b504e40f 100644 --- a/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/VscConverterStationImpl.java +++ b/network-store-iidm-impl/src/main/java/com/powsybl/network/store/iidm/impl/VscConverterStationImpl.java @@ -35,15 +35,15 @@ public HvdcType getHvdcType() { @Override public boolean isVoltageRegulatorOn() { - return getResource().getAttributes().getVoltageRegulatorOn(); + return this.isRegulating(); } @Override public VscConverterStationImpl setVoltageRegulatorOn(boolean voltageRegulatorOn) { ValidationUtil.checkVoltageControl(this, voltageRegulatorOn, getVoltageSetpoint(), getReactivePowerSetpoint(), ValidationLevel.STEADY_STATE_HYPOTHESIS, getNetwork().getReportNodeContext().getReportNode()); - boolean oldValue = getResource().getAttributes().getVoltageRegulatorOn(); + boolean oldValue = this.isRegulating(); if (voltageRegulatorOn != oldValue) { - updateResource(res -> res.getAttributes().setVoltageRegulatorOn(voltageRegulatorOn)); + this.setRegulating(voltageRegulatorOn); String variantId = index.getNetwork().getVariantManager().getWorkingVariantId(); index.notifyUpdate(this, "voltageRegulatorOn", variantId, oldValue, voltageRegulatorOn); } diff --git a/network-store-iidm-impl/src/test/java/com/powsybl/network/store/iidm/impl/GeneratorTest.java b/network-store-iidm-impl/src/test/java/com/powsybl/network/store/iidm/impl/GeneratorTest.java new file mode 100644 index 000000000..44cc6676f --- /dev/null +++ b/network-store-iidm-impl/src/test/java/com/powsybl/network/store/iidm/impl/GeneratorTest.java @@ -0,0 +1,65 @@ +/** + * Copyright (c) 2024, 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/. + */ +package com.powsybl.network.store.iidm.impl; + +import com.powsybl.iidm.network.Generator; +import com.powsybl.iidm.network.Load; +import com.powsybl.iidm.network.Network; +import com.powsybl.iidm.network.test.FourSubstationsNodeBreakerFactory; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.Test; + +/** + * @author Etienne Lesot + */ +class GeneratorTest { + + @Test + void testRegulationWhenRegulatedElementIsRemoved() { + Network network = FourSubstationsNodeBreakerFactory.create(); + + // initialization + Generator generator = network.getGenerator("GH3"); + Load load = network.getLoad("LD1"); + Assertions.assertTrue(generator.isVoltageRegulatorOn()); + Assertions.assertEquals(generator.getTerminal(), generator.getRegulatingTerminal()); + Assertions.assertEquals(400, generator.getTargetV()); + + // set the generator's regulation on the load terminal (both equipments are not on the same voltage level/bus) + generator.setRegulatingTerminal(load.getTerminal()); + generator.setTargetV(225); + Assertions.assertTrue(generator.isVoltageRegulatorOn()); + Assertions.assertEquals(load.getTerminal(), generator.getRegulatingTerminal()); + Assertions.assertEquals(225, generator.getTargetV()); + + // remove the load + network.getLoad("LD1").remove(); + Assertions.assertEquals(generator.getTerminal(), generator.getRegulatingTerminal()); + Assertions.assertFalse(generator.isVoltageRegulatorOn()); + } + + @Test + void testRegulationWhenRegulatedElementOnSameBusIsRemoved() { + Network network = FourSubstationsNodeBreakerFactory.create(); + + // initialization + Generator generator = network.getGenerator("GH3"); + Load load = network.getLoad("LD2"); + Assertions.assertTrue(generator.isVoltageRegulatorOn()); + Assertions.assertEquals(generator.getTerminal(), generator.getRegulatingTerminal()); + + // set the generator's regulation on the load terminal (both equipments are on the same voltage level/bus) + generator.setRegulatingTerminal(load.getTerminal()); + Assertions.assertTrue(generator.isVoltageRegulatorOn()); + Assertions.assertEquals(load.getTerminal(), generator.getRegulatingTerminal()); + + // remove the load + network.getLoad("LD2").remove(); + Assertions.assertEquals(generator.getTerminal(), generator.getRegulatingTerminal()); + Assertions.assertTrue(generator.isVoltageRegulatorOn()); + } +} diff --git a/network-store-model/src/main/java/com/powsybl/network/store/model/GeneratorAttributes.java b/network-store-model/src/main/java/com/powsybl/network/store/model/GeneratorAttributes.java index 0a1acb81a..ca1440be6 100644 --- a/network-store-model/src/main/java/com/powsybl/network/store/model/GeneratorAttributes.java +++ b/network-store-model/src/main/java/com/powsybl/network/store/model/GeneratorAttributes.java @@ -46,9 +46,6 @@ public class GeneratorAttributes extends AbstractRegulatingEquipmentAttributes i @Schema(description = "Maximum active power in MW") private double maxP; - @Schema(description = "Voltage regulation status") - private boolean voltageRegulatorOn; - @Schema(description = "Active power target in MW") private double targetP; diff --git a/network-store-model/src/main/java/com/powsybl/network/store/model/RegulatingPointAttributes.java b/network-store-model/src/main/java/com/powsybl/network/store/model/RegulatingPointAttributes.java index 0c0cc42f4..b4af0f53f 100644 --- a/network-store-model/src/main/java/com/powsybl/network/store/model/RegulatingPointAttributes.java +++ b/network-store-model/src/main/java/com/powsybl/network/store/model/RegulatingPointAttributes.java @@ -39,4 +39,7 @@ public class RegulatingPointAttributes extends AbstractAttributes implements Att @Schema(description = "Regulated equipment resource type") private ResourceType regulatedResourceType; + + @Schema(description = "is regulating") + private Boolean regulating; } diff --git a/network-store-model/src/main/java/com/powsybl/network/store/model/ShuntCompensatorAttributes.java b/network-store-model/src/main/java/com/powsybl/network/store/model/ShuntCompensatorAttributes.java index b02219e1b..8235ba563 100644 --- a/network-store-model/src/main/java/com/powsybl/network/store/model/ShuntCompensatorAttributes.java +++ b/network-store-model/src/main/java/com/powsybl/network/store/model/ShuntCompensatorAttributes.java @@ -53,9 +53,6 @@ public class ShuntCompensatorAttributes extends AbstractRegulatingEquipmentAttri @Schema(description = "Connectable position (for substation diagram)") private ConnectablePositionAttributes position; - @Schema(description = "Voltage regulation status") - private boolean voltageRegulatorOn; - @Schema(description = "targetV") private double targetV; diff --git a/network-store-model/src/main/java/com/powsybl/network/store/model/VscConverterStationAttributes.java b/network-store-model/src/main/java/com/powsybl/network/store/model/VscConverterStationAttributes.java index 0037975ff..fb0b4b882 100644 --- a/network-store-model/src/main/java/com/powsybl/network/store/model/VscConverterStationAttributes.java +++ b/network-store-model/src/main/java/com/powsybl/network/store/model/VscConverterStationAttributes.java @@ -40,9 +40,6 @@ public class VscConverterStationAttributes extends AbstractRegulatingEquipmentAt @Builder.Default private float lossFactor = Float.NaN; - @Schema(description = "Voltage regulator status") - private Boolean voltageRegulatorOn; - @Schema(description = "Reactive power set point in MVar") private double reactivePowerSetPoint; diff --git a/network-store-model/src/test/java/com/powsybl/network/store/model/TopLevelDocumentTest.java b/network-store-model/src/test/java/com/powsybl/network/store/model/TopLevelDocumentTest.java index b21780588..88ee9194e 100644 --- a/network-store-model/src/test/java/com/powsybl/network/store/model/TopLevelDocumentTest.java +++ b/network-store-model/src/test/java/com/powsybl/network/store/model/TopLevelDocumentTest.java @@ -95,7 +95,7 @@ public void testGenerator() throws IOException { TerminalRefAttributes regulatedTerminalAttributes = TerminalRefAttributes.builder().side("ONE").connectableId("idEq").build(); RegulatingPointAttributes regulatingPointAttributes = new RegulatingPointAttributes("gen1", GENERATOR, - new TerminalRefAttributes("gen1", null), regulatedTerminalAttributes, null, GENERATOR); + new TerminalRefAttributes("gen1", null), regulatedTerminalAttributes, null, GENERATOR, true); Map regEquipments = new HashMap<>(); regEquipments.put("gen1", GENERATOR); regEquipments.put("gen2", GENERATOR); @@ -123,7 +123,7 @@ public void testGenerator() throws IOException { TopLevelDocument document = TopLevelDocument.of(resourceGenerator); ObjectMapper objectMapper = JsonUtil.createObjectMapper(); String json = objectMapper.writeValueAsString(document); - String jsonRef = "{\"data\":[{\"type\":\"GENERATOR\",\"id\":\"gen1\",\"variantNum\":0,\"attributes\":{\"name\":\"name\",\"fictitious\":false,\"extensionAttributes\":{},\"regulatingPoint\":{\"regulatingEquipmentId\":\"gen1\",\"regulatingResourceType\":\"GENERATOR\",\"localTerminal\":{\"connectableId\":\"gen1\"},\"regulatingTerminal\":{\"connectableId\":\"idEq\",\"side\":\"ONE\"},\"regulationMode\":null,\"regulatedResourceType\":\"GENERATOR\"},\"voltageLevelId\":\"vl1\",\"node\":1,\"bus\":\"bus1\",\"energySource\":\"HYDRO\",\"minP\":2.0,\"maxP\":1.0,\"voltageRegulatorOn\":false,\"targetP\":3.0,\"targetQ\":0.0,\"targetV\":4.0,\"ratedS\":0.0,\"p\":NaN,\"q\":NaN,\"condenser\":false,\"regulatingEquipments\":{\"gen1\":\"GENERATOR\",\"gen2\":\"GENERATOR\"}}}],\"meta\":{}}"; + String jsonRef = "{\"data\":[{\"type\":\"GENERATOR\",\"id\":\"gen1\",\"variantNum\":0,\"attributes\":{\"name\":\"name\",\"fictitious\":false,\"extensionAttributes\":{},\"regulatingPoint\":{\"regulatingEquipmentId\":\"gen1\",\"regulatingResourceType\":\"GENERATOR\",\"localTerminal\":{\"connectableId\":\"gen1\"},\"regulatingTerminal\":{\"connectableId\":\"idEq\",\"side\":\"ONE\"},\"regulationMode\":null,\"regulatedResourceType\":\"GENERATOR\",\"regulating\":true},\"voltageLevelId\":\"vl1\",\"node\":1,\"bus\":\"bus1\",\"energySource\":\"HYDRO\",\"minP\":2.0,\"maxP\":1.0,\"targetP\":3.0,\"targetQ\":0.0,\"targetV\":4.0,\"ratedS\":0.0,\"p\":NaN,\"q\":NaN,\"condenser\":false,\"regulatingEquipments\":{\"gen1\":\"GENERATOR\",\"gen2\":\"GENERATOR\"}}}],\"meta\":{}}"; assertEquals(jsonRef, json); TopLevelDocument document2 = objectMapper.readValue(json, TopLevelDocument.class); assertEquals(resourceGenerator, document2.getData().get(0));