Skip to content

Commit

Permalink
Trip and lockout hvdc lines (#443)
Browse files Browse the repository at this point in the history
Signed-off-by: Ghazwa REHILI <[email protected]>
  • Loading branch information
ghazwarhili authored Mar 1, 2024
1 parent 5956e13 commit 01076a1
Show file tree
Hide file tree
Showing 6 changed files with 218 additions and 18 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -540,6 +540,11 @@ public List<Terminal> getTerminalsFromIdentifiable(Identifiable<?> identifiable)
w3t.getLeg2().getTerminal(),
w3t.getLeg3().getTerminal()
).toList();
} else if (identifiable instanceof HvdcLine hvdcLine) {
return Stream.of(
hvdcLine.getConverterStation1().getTerminal(),
hvdcLine.getConverterStation2().getTerminal()
).toList();
}
throw NetworkModificationException.createEquipmentTypeNotSupported(identifiable.getClass().getSimpleName());
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import com.powsybl.commons.reporter.Reporter;
import com.powsybl.commons.reporter.TypedValue;
import com.powsybl.iidm.modification.tripping.BranchTripping;
import com.powsybl.iidm.modification.tripping.HvdcLineTripping;
import com.powsybl.iidm.modification.tripping.ThreeWindingsTransformerTripping;
import com.powsybl.iidm.modification.tripping.Tripping;
import com.powsybl.iidm.network.*;
Expand All @@ -22,7 +23,6 @@

import java.util.HashSet;
import java.util.Objects;
import java.util.stream.Collectors;

import static org.gridsuite.modification.server.NetworkModificationException.Type.EQUIPMENT_NOT_FOUND;
import static org.gridsuite.modification.server.NetworkModificationException.Type.OPERATING_STATUS_MODIFICATION_ERROR;
Expand Down Expand Up @@ -95,9 +95,9 @@ private void applyTripEquipment(Reporter subReporter, Identifiable<?> equipment,

LOGGER.info("Apply Trip on {} {}, switchesToDisconnect: {} terminalsToDisconnect: {} traversedTerminals: {}",
equipmentType, equipment.getId(),
switchesToDisconnect.stream().map(Identifiable::getId).collect(Collectors.toList()),
terminalsToDisconnect.stream().map(Terminal::getConnectable).map(Identifiable::getId).collect(Collectors.toList()),
traversedTerminals.stream().map(Terminal::getConnectable).map(Identifiable::getId).collect(Collectors.toList()));
switchesToDisconnect.stream().map(Identifiable::getId).toList(),
terminalsToDisconnect.stream().map(Terminal::getConnectable).map(Identifiable::getId).toList(),
traversedTerminals.stream().map(Terminal::getConnectable).map(Identifiable::getId).toList());

switchesToDisconnect.forEach(sw -> sw.setOpen(true));
terminalsToDisconnect.forEach(Terminal::disconnect);
Expand All @@ -109,10 +109,13 @@ private void applyTripEquipment(Reporter subReporter, Identifiable<?> equipment,
.withSeverity(TypedValue.INFO_SEVERITY)
.build());

traversedTerminals.stream().map(t -> network.getIdentifiable(t.getConnectable().getId()))
traversedTerminals.stream()
.map(t -> network.getIdentifiable(t.getConnectable().getId()))
.filter(Objects::nonNull)
.filter(distinctByKey(Identifiable::getId)) // dont process the same equipment more than once
.forEach(b -> b.newExtension(OperatingStatusAdder.class).withStatus(OperatingStatus.Status.FORCED_OUTAGE).add());
.filter(distinctByKey(Identifiable::getId))
.forEach(b -> equipment.newExtension(OperatingStatusAdder.class)
.withStatus(OperatingStatus.Status.FORCED_OUTAGE)
.add());
}

private void applySwitchOnEquipment(Reporter subReporter, Identifiable<?> equipment, String equipmentType) {
Expand Down Expand Up @@ -176,6 +179,8 @@ public Tripping getTrippingFromIdentifiable(Identifiable<?> identifiable) {
return new BranchTripping(branch.getId());
} else if (identifiable instanceof ThreeWindingsTransformer w3t) {
return new ThreeWindingsTransformerTripping(w3t.getId());
} else if (identifiable instanceof HvdcLine hvdcLine) {
return new HvdcLineTripping(hvdcLine.getId());
}
throw NetworkModificationException.createEquipmentTypeNotSupported(identifiable.getClass().getSimpleName());
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
/**
* 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 org.gridsuite.modification.server.modifications;

import com.fasterxml.jackson.core.type.TypeReference;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.extensions.OperatingStatus;
import lombok.SneakyThrows;
import org.gridsuite.modification.server.dto.ModificationInfos;
import org.gridsuite.modification.server.dto.OperatingStatusModificationInfos;
import org.gridsuite.modification.server.utils.NetworkCreation;
import org.gridsuite.modification.server.utils.TestUtils;
import org.junit.jupiter.api.Tag;

import java.util.Map;
import java.util.UUID;

import static com.powsybl.iidm.network.extensions.OperatingStatus.Status.FORCED_OUTAGE;
import static com.powsybl.iidm.network.extensions.OperatingStatus.Status.PLANNED_OUTAGE;
import static org.junit.jupiter.api.Assertions.assertEquals;

@Tag("IntegrationTest")
public class OperatingStatusModificationLockoutHvdcLineTest extends AbstractNetworkModificationTest {

private static final String TARGET_HVDC_LINE_ID = "hvdcLine";

private static final OperatingStatus.Status TARGET_HVDC_LINE_STATUS = PLANNED_OUTAGE;
private static final OperatingStatus.Status OTHER_HVDC_LINE_STATUS = FORCED_OUTAGE;

@Override
protected Network createNetwork(UUID networkUuid) {
Network network = NetworkCreation.create(networkUuid, true);
// force operating status different from the expected one, after testCreate
TestUtils.setOperatingStatus(network, TARGET_HVDC_LINE_ID, OTHER_HVDC_LINE_STATUS);
return network;
}

@Override
protected ModificationInfos buildModification() {
return OperatingStatusModificationInfos.builder()
.stashed(false)
.equipmentId(TARGET_HVDC_LINE_ID)
.energizedVoltageLevelId("energizedVoltageLevelId")
.action(OperatingStatusModificationInfos.ActionType.LOCKOUT).build();
}

@Override
protected ModificationInfos buildModificationUpdate() {
return OperatingStatusModificationInfos.builder()
.stashed(false)
.equipmentId("hvdcLineEdited")
.energizedVoltageLevelId("energizedVoltageLevelId")
.action(OperatingStatusModificationInfos.ActionType.LOCKOUT).build();
}

@Override
protected void assertAfterNetworkModificationCreation() {
TestUtils.assertOperatingStatus(getNetwork(), TARGET_HVDC_LINE_ID, TARGET_HVDC_LINE_STATUS);
}

@Override
protected void assertAfterNetworkModificationDeletion() {
// go back to init status
TestUtils.assertOperatingStatus(getNetwork(), TARGET_HVDC_LINE_ID, OTHER_HVDC_LINE_STATUS);
}

@Override
@SneakyThrows
protected void testCreationModificationMessage(ModificationInfos modificationInfos) {
assertEquals("OPERATING_STATUS_MODIFICATION", modificationInfos.getMessageType());
Map<String, String> createdValues = mapper.readValue(modificationInfos.getMessageValues(), new TypeReference<>() { });
assertEquals("energizedVoltageLevelId", createdValues.get("energizedVoltageLevelId"));
assertEquals("LOCKOUT", createdValues.get("action"));
assertEquals("hvdcLine", createdValues.get("equipmentId"));
}

@Override
@SneakyThrows
protected void testUpdateModificationMessage(ModificationInfos modificationInfos) {
assertEquals("OPERATING_STATUS_MODIFICATION", modificationInfos.getMessageType());
Map<String, String> updatedValues = mapper.readValue(modificationInfos.getMessageValues(), new TypeReference<>() { });
assertEquals("energizedVoltageLevelId", updatedValues.get("energizedVoltageLevelId"));
assertEquals("LOCKOUT", updatedValues.get("action"));
assertEquals("hvdcLineEdited", updatedValues.get("equipmentId"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
public class OperatingStatusModificationTrip2WTransformerTest extends AbstractNetworkModificationTest {

private static final String TARGET_BRANCH_ID = "trf1";
private static final String UPDATE_BRANCH_ID = "line1"; // it is not a 2WT, but is does not matter
private static final String UPDATE_BRANCH_ID = "trf1Edited";
private static final OperatingStatus.Status TARGET_BRANCH_STATUS = FORCED_OUTAGE;
private static final OperatingStatus.Status OTHER_BRANCH_STATUS = PLANNED_OUTAGE;

Expand Down Expand Up @@ -85,6 +85,6 @@ protected void testUpdateModificationMessage(ModificationInfos modificationInfos
Map<String, String> updatedValues = mapper.readValue(modificationInfos.getMessageValues(), new TypeReference<>() { });
assertEquals("energizedVoltageLevelIdEdited", updatedValues.get("energizedVoltageLevelId"));
assertEquals("SWITCH_ON", updatedValues.get("action"));
assertEquals("line1", updatedValues.get("equipmentId"));
assertEquals("trf1Edited", updatedValues.get("equipmentId"));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* 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 org.gridsuite.modification.server.modifications;

import com.fasterxml.jackson.core.type.TypeReference;
import com.powsybl.iidm.network.HvdcLine;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.extensions.OperatingStatus;
import lombok.SneakyThrows;
import org.gridsuite.modification.server.dto.ModificationInfos;
import org.gridsuite.modification.server.dto.OperatingStatusModificationInfos;
import org.gridsuite.modification.server.utils.NetworkCreation;
import org.gridsuite.modification.server.utils.TestUtils;
import org.junit.Assert;
import org.junit.jupiter.api.Tag;

import java.util.Map;
import java.util.UUID;

import static com.powsybl.iidm.network.extensions.OperatingStatus.Status.FORCED_OUTAGE;
import static com.powsybl.iidm.network.extensions.OperatingStatus.Status.PLANNED_OUTAGE;
import static org.junit.jupiter.api.Assertions.assertEquals;

@Tag("IntegrationTest")
public class OperatingStatusModificationTripHvdcLineTest extends AbstractNetworkModificationTest {

private static final String TARGET_HVDC_LINE_ID = "hvdcLine";

private static final OperatingStatus.Status TARGET_HVDC_LINE_STATUS = FORCED_OUTAGE;
private static final OperatingStatus.Status OTHER_HVDC_LINE_STATUS = PLANNED_OUTAGE;

@Override
protected Network createNetwork(UUID networkUuid) {
Network network = NetworkCreation.create(networkUuid, true);
// force operating status different from the expected one, after testCreate
TestUtils.setOperatingStatus(network, TARGET_HVDC_LINE_ID, OTHER_HVDC_LINE_STATUS);
return network;
}

@Override
protected ModificationInfos buildModification() {
return OperatingStatusModificationInfos.builder()
.stashed(false)
.equipmentId(TARGET_HVDC_LINE_ID)
.energizedVoltageLevelId("energizedVoltageLevelId")
.action(OperatingStatusModificationInfos.ActionType.TRIP).build();
}

@Override
protected ModificationInfos buildModificationUpdate() {
return OperatingStatusModificationInfos.builder()
.stashed(false)
.equipmentId("hvdcLineEdited")
.energizedVoltageLevelId("energizedVoltageLevelId")
.action(OperatingStatusModificationInfos.ActionType.TRIP).build();
}

@Override
protected void assertAfterNetworkModificationCreation() {
TestUtils.assertOperatingStatus(getNetwork(), TARGET_HVDC_LINE_ID, TARGET_HVDC_LINE_STATUS);
assertTerminalsStatusAfterNetworkModification(false);
}

@Override
protected void assertAfterNetworkModificationDeletion() {
// go back to init status
TestUtils.assertOperatingStatus(getNetwork(), TARGET_HVDC_LINE_ID, OTHER_HVDC_LINE_STATUS);
assertTerminalsStatusAfterNetworkModification(true);
}

@Override
@SneakyThrows
protected void testCreationModificationMessage(ModificationInfos modificationInfos) {
assertEquals("OPERATING_STATUS_MODIFICATION", modificationInfos.getMessageType());
Map<String, String> createdValues = mapper.readValue(modificationInfos.getMessageValues(), new TypeReference<>() { });
assertEquals("energizedVoltageLevelId", createdValues.get("energizedVoltageLevelId"));
assertEquals("TRIP", createdValues.get("action"));
assertEquals("hvdcLine", createdValues.get("equipmentId"));
}

@Override
@SneakyThrows
protected void testUpdateModificationMessage(ModificationInfos modificationInfos) {
assertEquals("OPERATING_STATUS_MODIFICATION", modificationInfos.getMessageType());
Map<String, String> updatedValues = mapper.readValue(modificationInfos.getMessageValues(), new TypeReference<>() { });
assertEquals("energizedVoltageLevelId", updatedValues.get("energizedVoltageLevelId"));
assertEquals("TRIP", updatedValues.get("action"));
assertEquals("hvdcLineEdited", updatedValues.get("equipmentId"));
}

private void assertTerminalsStatusAfterNetworkModification(boolean shouldBeConnected) {
HvdcLine hvdcLine = getNetwork().getHvdcLine(TARGET_HVDC_LINE_ID);
Assert.assertEquals(hvdcLine.getConverterStation1().getTerminal().isConnected(), shouldBeConnected);
Assert.assertEquals(hvdcLine.getConverterStation2().getTerminal().isConnected(), shouldBeConnected);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import com.powsybl.commons.exceptions.UncheckedInterruptedException;
import com.powsybl.commons.reporter.Report;
import com.powsybl.commons.reporter.ReporterModel;
import com.powsybl.iidm.network.Branch;
import com.powsybl.iidm.network.Identifiable;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.extensions.OperatingStatus;
import com.powsybl.iidm.network.extensions.OperatingStatusAdder;
Expand Down Expand Up @@ -98,20 +98,20 @@ public static void assertRequestsCount(long select, long insert, long update, lo
}

@SuppressWarnings("unchecked")
public static void assertOperatingStatus(Network network, String branchName, OperatingStatus.Status status) {
public static void assertOperatingStatus(Network network, String identifiableName, OperatingStatus.Status status) {
assertNotNull(network);
Branch<?> branch = network.getBranch(branchName);
assertNotNull(branch);
OperatingStatus operatingStatus = branch.getExtensionByName("operatingStatus");
Identifiable<?> identifiable = network.getIdentifiable(identifiableName);
assertNotNull(identifiable);
OperatingStatus operatingStatus = identifiable.getExtensionByName("operatingStatus");
assertNotNull(operatingStatus);
assertEquals(status, operatingStatus.getStatus());
}

@SuppressWarnings("unchecked")
public static void setOperatingStatus(Network network, String branchName, OperatingStatus.Status status) {
Branch<?> branch = network.getBranch(branchName);
assertNotNull(branch);
branch.newExtension(OperatingStatusAdder.class).withStatus(status).add();
public static void setOperatingStatus(Network network, String identifiableName, OperatingStatus.Status status) {
Identifiable<?> identifiable = network.getIdentifiable(identifiableName);
assertNotNull(identifiable);
identifiable.newExtension(OperatingStatusAdder.class).withStatus(status).add();
}

public static String resourceToString(String resource) throws IOException {
Expand Down

0 comments on commit 01076a1

Please sign in to comment.