Skip to content

Commit

Permalink
add controls on ipMin/ipMax in voltage level modifications (#404)
Browse files Browse the repository at this point in the history
Signed-off-by: David BRAQUART <david.braquart@rte-france.com>
  • Loading branch information
dbraquart authored Dec 22, 2023
1 parent 2882a7a commit e842643
Show file tree
Hide file tree
Showing 6 changed files with 219 additions and 17 deletions.
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

0 comments on commit e842643

Please sign in to comment.