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 controls on ipMin/ipMax in voltage level modifications #404

Merged
Merged
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 @@ -256,9 +256,19 @@ public void controlVoltageLevelCreation(VoltageLevelCreationInfos voltageLevelCr
throw new NetworkModificationException(CREATE_VOLTAGE_LEVEL_ERROR,
"Coupling between same bus bar section is not allowed");
}
if (Objects.nonNull(voltageLevelCreationInfos.getIpMin()) && voltageLevelCreationInfos.getIpMin() < 0) {
throw new NetworkModificationException(CREATE_VOLTAGE_LEVEL_ERROR, "IpMin must be positive");
}
if (Objects.nonNull(voltageLevelCreationInfos.getIpMax()) && voltageLevelCreationInfos.getIpMax() < 0) {
throw new NetworkModificationException(CREATE_VOLTAGE_LEVEL_ERROR, "IpMax must be positive");
}
if (Objects.nonNull(voltageLevelCreationInfos.getIpMin()) && Objects.isNull(voltageLevelCreationInfos.getIpMax())) {
throw new NetworkModificationException(CREATE_VOLTAGE_LEVEL_ERROR, "IpMax is required");
}
if (Objects.nonNull(voltageLevelCreationInfos.getIpMin()) && Objects.nonNull(voltageLevelCreationInfos.getIpMax())
&& voltageLevelCreationInfos.getIpMin() > voltageLevelCreationInfos.getIpMax()) {
throw new NetworkModificationException(CREATE_VOLTAGE_LEVEL_ERROR, "IpMin cannot be greater than IpMax");
}
}

private boolean checkBbs(Network network, String busbarSectionId1, String busbarSectionId2, Reporter subReporter) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,17 +10,16 @@
import com.powsybl.commons.reporter.Report;
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.commons.reporter.TypedValue;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.IdentifiableShortCircuit;
import com.powsybl.iidm.network.extensions.IdentifiableShortCircuitAdder;
import org.gridsuite.modification.server.NetworkModificationException;
import org.gridsuite.modification.server.dto.VoltageLevelModificationInfos;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

import static org.gridsuite.modification.server.NetworkModificationException.Type.VOLTAGE_LEVEL_NOT_FOUND;
import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_VOLTAGE_LEVEL_ERROR;

/**
* @author Seddik Yengui <Seddik.yengui at rte-france.com>
Expand All @@ -35,20 +34,49 @@ public VoltageLevelModification(VoltageLevelModificationInfos voltageLevelModifi

@Override
public void check(Network network) throws NetworkModificationException {
VoltageLevel voltageLevel = network.getVoltageLevel(modificationInfos.getEquipmentId());
if (voltageLevel == null) {
throw new NetworkModificationException(VOLTAGE_LEVEL_NOT_FOUND,
String.format("Voltage level %s does not exist in network", modificationInfos.getEquipmentId()));
boolean ipMinSet = false;
boolean ipMaxSet = false;
if (Objects.nonNull(modificationInfos.getIpMin())) {
ipMinSet = true;
if (modificationInfos.getIpMin().getValue() < 0) {
throw new NetworkModificationException(MODIFY_VOLTAGE_LEVEL_ERROR, "IpMin must be positive");
}
}
if (Objects.nonNull(modificationInfos.getIpMax())) {
ipMaxSet = true;
if (modificationInfos.getIpMax().getValue() < 0) {
throw new NetworkModificationException(MODIFY_VOLTAGE_LEVEL_ERROR, "IpMax must be positive");
}
}
if (ipMinSet && ipMaxSet) {
if (modificationInfos.getIpMin().getValue() > modificationInfos.getIpMax().getValue()) {
throw new NetworkModificationException(MODIFY_VOLTAGE_LEVEL_ERROR, "IpMin cannot be greater than IpMax");
}
} else if (ipMinSet || ipMaxSet) {
// only one Icc set: check with existing VL attributes
checkIccValuesAgainstEquipmentInNetwork(network, ipMinSet, ipMaxSet);
}
}

private void checkIccValuesAgainstEquipmentInNetwork(Network network, boolean ipMinSet, boolean ipMaxSet) {
VoltageLevel existingVoltageLevel = ModificationUtils.getInstance().getVoltageLevel(network, modificationInfos.getEquipmentId());
IdentifiableShortCircuit<VoltageLevel> identifiableShortCircuit = existingVoltageLevel.getExtension(IdentifiableShortCircuit.class);
if (Objects.isNull(identifiableShortCircuit)) {
if (ipMinSet) {
throw new NetworkModificationException(MODIFY_VOLTAGE_LEVEL_ERROR, "IpMax is required");
}
} else {
if (ipMinSet && modificationInfos.getIpMin().getValue() > identifiableShortCircuit.getIpMax() ||
ipMaxSet && identifiableShortCircuit.getIpMin() > modificationInfos.getIpMax().getValue()) {
throw new NetworkModificationException(MODIFY_VOLTAGE_LEVEL_ERROR, "IpMin cannot be greater than IpMax");
}
}
}

@Override
public void apply(Network network, Reporter subReporter) {
VoltageLevel voltageLevel = network.getVoltageLevel(modificationInfos.getEquipmentId());
modifyVoltageLevel(subReporter, voltageLevel);
}
VoltageLevel voltageLevel = ModificationUtils.getInstance().getVoltageLevel(network, modificationInfos.getEquipmentId());

private void modifyVoltageLevel(Reporter subReporter, VoltageLevel voltageLevel) {
subReporter.report(Report.builder()
.withKey("voltageLevelModification")
.withDefaultMessage("Voltage level with id=${id} modified :")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,47 @@ public void testCreateWithBbsNotExist() throws Exception {
assertNotNull(getNetwork().getVoltageLevel("vl_2"));
}

@Test
public void testIpMinEqualsIpMax() throws Exception {
VoltageLevelCreationInfos vli = (VoltageLevelCreationInfos) buildModification();
vli.setEquipmentId("vl_ok");
vli.setIpMin(25.0);
vli.setIpMax(25.0);
String vliJsonObject = mapper.writeValueAsString(vli);
mockMvc.perform(post(getNetworkModificationUri()).content(vliJsonObject).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
// VL is created
assertNotNull(getNetwork().getVoltageLevel("vl_ok"));
}

private void testIccWithError(Double ipMin, Double ipMax, String reportError) throws Exception {
VoltageLevelCreationInfos vli = (VoltageLevelCreationInfos) buildModification();
vli.setEquipmentId("vl_ko");
vli.setIpMin(ipMin);
vli.setIpMax(ipMax);
String vliJsonObject = mapper.writeValueAsString(vli);
mockMvc.perform(post(getNetworkModificationUri()).content(vliJsonObject).contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
// VL could not have been created
assertNull(getNetwork().getVoltageLevel("vl_ko"));
assertLogMessage(new NetworkModificationException(CREATE_VOLTAGE_LEVEL_ERROR, reportError).getMessage(), vli.getErrorType().name(), reportService);
}

@Test
public void testIpMinGreaterThanIpMax() throws Exception {
testIccWithError(15.1, 15.0, "IpMin cannot be greater than IpMax");
}

@Test
public void testIpMinNegative() throws Exception {
testIccWithError(-25.0, 15.0, "IpMin must be positive");
}

@Test
public void testIpMaxNegative() throws Exception {
testIccWithError(25.0, -15.0, "IpMax must be positive");
}

public void testCreateWithShortCircuitExtension() throws Exception {
VoltageLevelCreationInfos vli = (VoltageLevelCreationInfos) buildModification();
vli.setIpMin(null);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,10 @@
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.iidm.network.extensions.IdentifiableShortCircuit;
import com.powsybl.iidm.network.extensions.IdentifiableShortCircuitAdder;
import lombok.SneakyThrows;
import org.gridsuite.modification.server.dto.AttributeModification;
import org.gridsuite.modification.server.dto.ModificationInfos;
import org.gridsuite.modification.server.dto.OperationType;
import org.gridsuite.modification.server.dto.VoltageLevelModificationInfos;
import org.gridsuite.modification.server.NetworkModificationException;
import org.gridsuite.modification.server.dto.*;
import org.gridsuite.modification.server.utils.NetworkCreation;
import org.junit.Test;
import org.junit.jupiter.api.Tag;
Expand All @@ -24,6 +23,8 @@
import java.util.Map;
import java.util.UUID;

import static org.gridsuite.modification.server.NetworkModificationException.Type.MODIFY_VOLTAGE_LEVEL_ERROR;
import static org.gridsuite.modification.server.utils.TestUtils.assertLogMessage;
import static org.junit.Assert.*;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.post;
Expand Down Expand Up @@ -121,6 +122,120 @@ public void testModifyShortCircuitExtension() throws Exception {
assertEquals(0.2, identifiableShortCircuit2.getIpMin(), 0);
}

private void testIpMinIpMaxNotChanged(Double ipMin, Double ipMax, String reportError) throws Exception {
final String vlWithBothIcc = "v3";
final double beforeUpdateIpMin = 15.0; // cf NetworkCreation.java
final double beforeUpdateIpMax = 25.0;

VoltageLevelModificationInfos vli = VoltageLevelModificationInfos.builder()
.stashed(false)
.equipmentId(vlWithBothIcc)
.build();
if (ipMin != null) {
vli.setIpMin(new AttributeModification<>(ipMin, OperationType.SET));
}
if (ipMax != null) {
vli.setIpMax(new AttributeModification<>(ipMax, OperationType.SET));
}
applyModification(vli);

// check the update has not been made
VoltageLevel voltageLevelUpdated = getNetwork().getVoltageLevel(vlWithBothIcc);
assertNotNull(voltageLevelUpdated);
IdentifiableShortCircuit<VoltageLevel> identifiableShortCircuit1 = voltageLevelUpdated.getExtension(IdentifiableShortCircuit.class);
assertNotNull(identifiableShortCircuit1);
assertEquals(beforeUpdateIpMin, identifiableShortCircuit1.getIpMin(), 0);
assertEquals(beforeUpdateIpMax, identifiableShortCircuit1.getIpMax(), 0);
assertLogMessage(new NetworkModificationException(MODIFY_VOLTAGE_LEVEL_ERROR, reportError).getMessage(), vli.getErrorType().name(), reportService);
}

@Test
public void testIpMinGreaterThanIpMax() throws Exception {
// check only modification inputs
testIpMinIpMaxNotChanged(30.0, 29.0, "IpMin cannot be greater than IpMax");
}

@Test
public void testIpMinNegative() throws Exception {
// check only modification inputs
testIpMinIpMaxNotChanged(-30.0, 0.0, "IpMin must be positive");
}

@Test
public void testIpMaxNegative() throws Exception {
// check only modification inputs
testIpMinIpMaxNotChanged(0.0, -12.0, "IpMax must be positive");
}

@Test
public void testIpMinGreaterThanEquipmentIpMax() throws Exception {
// check ipMin modification input against equipement ipMax real value (25.0)
testIpMinIpMaxNotChanged(30.0, null, "IpMin cannot be greater than IpMax");
}

@Test
public void testEquipmentIpMinGreaterThanIpMax() throws Exception {
// check ipMax modification input against equipement ipMin real value (15.0)
testIpMinIpMaxNotChanged(null, 14.9, "IpMin cannot be greater than IpMax");
}

@Test
public void testIpMinEqualsIpMax() throws Exception {
final String vlWithBothIcc = "v3";
final double iccValue = 29.0;
VoltageLevelModificationInfos vli = (VoltageLevelModificationInfos) buildModification();
vli.setIpMin(new AttributeModification<>(iccValue, OperationType.SET));
vli.setIpMax(new AttributeModification<>(iccValue, OperationType.SET));
vli.setEquipmentId(vlWithBothIcc);
applyModification(vli);

// check the update has been made
VoltageLevel voltageLevelUpdated = getNetwork().getVoltageLevel(vlWithBothIcc);
assertNotNull(voltageLevelUpdated);
IdentifiableShortCircuit<VoltageLevel> identifiableShortCircuit1 = voltageLevelUpdated.getExtension(IdentifiableShortCircuit.class);
assertNotNull(identifiableShortCircuit1);
assertEquals(iccValue, identifiableShortCircuit1.getIpMin(), 0);
assertEquals(iccValue, identifiableShortCircuit1.getIpMax(), 0);
}

@Test
public void testSetIpMinOnEquipmentWithoutExtension() throws Exception {
final String vlWithNoIcc = "v2";
VoltageLevelModificationInfos vli = VoltageLevelModificationInfos.builder()
.stashed(false)
.equipmentId(vlWithNoIcc)
.ipMin(new AttributeModification<>(10.0, OperationType.SET))
.build();
applyModification(vli);
// check the update has not been made
VoltageLevel voltageLevelUpdated = getNetwork().getVoltageLevel(vlWithNoIcc);
assertNotNull(voltageLevelUpdated);
assertNull(voltageLevelUpdated.getExtension(IdentifiableShortCircuit.class));
assertLogMessage(new NetworkModificationException(MODIFY_VOLTAGE_LEVEL_ERROR, "IpMax is required").getMessage(), vli.getErrorType().name(), reportService);
}

@Test
public void testSetIpMaxOnEquipmentWitOnlyIpMaxExtension() throws Exception {
final String vlName = "v2"; // has no ICC
getNetwork().getVoltageLevel(vlName)
.newExtension(IdentifiableShortCircuitAdder.class).withIpMax(30.0).add();

final double targetIpMax = 29.0;
VoltageLevelModificationInfos vli = VoltageLevelModificationInfos.builder()
.stashed(false)
.equipmentId(vlName)
.ipMax(new AttributeModification<>(targetIpMax, OperationType.SET))
.build();
applyModification(vli);
// check the update has been made
VoltageLevel voltageLevelUpdated = getNetwork().getVoltageLevel(vlName);
assertNotNull(voltageLevelUpdated);
IdentifiableShortCircuit<VoltageLevel> identifiableShortCircuit1 = voltageLevelUpdated.getExtension(IdentifiableShortCircuit.class);
assertNotNull(identifiableShortCircuit1);
assertEquals(0, identifiableShortCircuit1.getIpMin(), 0);
assertEquals(targetIpMax, identifiableShortCircuit1.getIpMax(), 0);
}

private void applyModification(VoltageLevelModificationInfos infos) throws Exception {
mockMvc.perform(post(getNetworkModificationUri())
.content(mapper.writeValueAsString(infos))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ public static Network create(UUID uuid, boolean createHvdcLine, NetworkFactory n
createStaticVarCompensator(v6, "v6Compensator", "v6Compensator", 5, StaticVarCompensator.RegulationMode.VOLTAGE, 380., 100, 2, 30);

Substation s2 = createSubstation(network, "s2", "s2", Country.FR);
VoltageLevel v3 = createVoltageLevel(s2, "v3", "v3", TopologyKind.NODE_BREAKER, 380.0);
VoltageLevel v3 = createVoltageLevel(s2, "v3", "v3", TopologyKind.NODE_BREAKER, 380.0, 15.0, 25.0);
createBusBarSection(v3, "3A", "3A", 0);

createLoad(v3, "v3load", "v3load", 2, 0., 0., "cn3", 3, ConnectablePosition.Direction.BOTTOM);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.powsybl.iidm.network.extensions.BusbarSectionPositionAdder;
import com.powsybl.iidm.network.extensions.ConnectablePosition;
import com.powsybl.iidm.network.extensions.ConnectablePositionAdder;
import com.powsybl.iidm.network.extensions.IdentifiableShortCircuitAdder;

public final class NetworkUtil {

Expand All @@ -37,6 +38,13 @@ public static VoltageLevel createVoltageLevel(Substation s, String id, String na
.add();
}

public static VoltageLevel createVoltageLevel(Substation s, String id, String name,
TopologyKind topology, double vNom, double ipMin, double ipMax) {
VoltageLevel vl = createVoltageLevel(s, id, name, topology, vNom);
vl.newExtension(IdentifiableShortCircuitAdder.class).withIpMin(ipMin).withIpMax(ipMax).add();
return vl;
}

public static void createBusBarSection(VoltageLevel vl, String id, String name, int node) {
var bbs = vl.getNodeBreakerView().newBusbarSection()
.setId(id)
Expand Down
Loading