Skip to content

Commit

Permalink
Merge branch 'main' into operational_limits_test
Browse files Browse the repository at this point in the history
  • Loading branch information
zamarrenolm authored Oct 14, 2024
2 parents 8701006 + cdee51a commit 8961560
Show file tree
Hide file tree
Showing 13 changed files with 174 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,47 +7,58 @@
*/
package com.powsybl.security;

import com.powsybl.iidm.network.Network;

import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
* @author Étienne Lesot {@literal <etienne.lesot at rte-france.com>}
*/
public class BusBreakerViolationLocation implements ViolationLocation {
private final String voltageLevelId;
private final String busId;
private final List<String> busIds;

public BusBreakerViolationLocation(String voltageLevelId, String busId) {
Objects.requireNonNull(voltageLevelId, "voltageLevelId");
this.voltageLevelId = voltageLevelId;
this.busId = busId;
/**
* Create a ViolationLocation for a violation detected in a voltage level in bus/breaker topology.
* @param busIds The ids of the <b>configured</b> buses (of the bus/breaker view) where the violation was detected.
*/
public BusBreakerViolationLocation(List<String> busIds) {
this.busIds = Objects.requireNonNull(busIds, "busIds should not be null.");
}

@Override
public String getVoltageLevelId() {
return voltageLevelId;
/**
* Get the ids of the <b>configured</b> buses (of the bus/breaker view) where the violation was detected.
* @return the configured bus ids
*/
public List<String> getBusIds() {
return busIds;
}

@Override
public Optional<String> getBusId() {
return Optional.ofNullable(busId);
public Type getType() {
return Type.BUS_BREAKER;
}

@Override
public String getId() {
return busId == null ? voltageLevelId : busId;
public String toString() {
return "BusBreakerViolationLocation{" +
"busIds='" + busIds + '\'' +
'}';
}

@Override
public Type getType() {
return Type.BUS_BREAKER;
public BusView getBusView(Network network) {
return () -> busIds.stream()
.map(id -> network.getBusBreakerView().getBus(id))
.filter(b -> b.getConnectedTerminalCount() > 0)
.map(b -> b.getConnectedTerminals().iterator().next().getBusView().getBus())
.distinct();

}

@Override
public String toString() {
return "BusBreakerViolationLocation{" +
"voltageLevelId='" + voltageLevelId + '\'' +
", busId='" + busId + '\'' +
'}';
public BusView getBusBreakerView(Network network) {
return () -> busIds.stream().map(id -> network.getBusBreakerView().getBus(id));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,11 @@
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.limitmodification.LimitsComputer;
import com.powsybl.iidm.network.util.LimitViolationUtils;
import com.powsybl.iidm.network.util.Networks;
import com.powsybl.iidm.network.util.PermanentLimitCheckResult;
import com.powsybl.security.detectors.LoadingLimitType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.List;
import java.util.Set;
Expand All @@ -23,6 +26,8 @@
*/
public final class LimitViolationDetection {

private static final Logger LOGGER = LoggerFactory.getLogger(LimitViolationDetection.class);

private LimitViolationDetection() {
}

Expand Down Expand Up @@ -206,15 +211,14 @@ private static void checkVoltage(Bus bus, Consumer<LimitViolation> consumer) {

static void checkVoltage(Bus bus, double value, Consumer<LimitViolation> consumer) {
VoltageLevel vl = bus.getVoltageLevel();
ViolationLocation voltageViolationLocation = createViolationLocation(bus);
if (!Double.isNaN(vl.getLowVoltageLimit()) && value <= vl.getLowVoltageLimit()) {
consumer.accept(new LimitViolation(vl.getId(), vl.getOptionalName().orElse(null), LimitViolationType.LOW_VOLTAGE,
vl.getLowVoltageLimit(), 1., value, voltageViolationLocation));
vl.getLowVoltageLimit(), 1., value, createViolationLocation(bus)));
}

if (!Double.isNaN(vl.getHighVoltageLimit()) && value >= vl.getHighVoltageLimit()) {
consumer.accept(new LimitViolation(vl.getId(), vl.getOptionalName().orElse(null), LimitViolationType.HIGH_VOLTAGE,
vl.getHighVoltageLimit(), 1., value, voltageViolationLocation));
vl.getHighVoltageLimit(), 1., value, createViolationLocation(bus)));
}
}

Expand Down Expand Up @@ -268,14 +272,18 @@ static void checkVoltageAngle(VoltageAngleLimit voltageAngleLimit, double value,
public static ViolationLocation createViolationLocation(Bus bus) {
VoltageLevel vl = bus.getVoltageLevel();
if (vl.getTopologyKind() == TopologyKind.NODE_BREAKER) {
List<String> busbarIds = bus.getConnectedTerminalStream()
.map(Terminal::getConnectable)
.filter(BusbarSection.class::isInstance)
.map(Connectable::getId)
.toList();
return new NodeBreakerViolationLocation(vl.getId(), busbarIds);
List<Integer> nodes = Networks.getNodesByBus(vl).get(bus.getId()).stream().toList();
return new NodeBreakerViolationLocation(vl.getId(), nodes);
} else {
return new BusBreakerViolationLocation(vl.getId(), bus.getId());
try {
List<String> configuredBusIds = vl.getBusBreakerView().getBusStreamFromBusViewBusId(bus.getId())
.map(Identifiable::getId)
.sorted().toList();
return new BusBreakerViolationLocation(configuredBusIds);
} catch (Exception e) {
LOGGER.error("Error generating ViolationLocation", e);
return null;
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
*/
package com.powsybl.security;

import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.iidm.network.util.Networks;

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

Expand All @@ -15,27 +19,43 @@
*/
public class NodeBreakerViolationLocation implements ViolationLocation {
private final String voltageLevelId;
private final List<String> busBarIds;
private final List<Integer> nodes;

public NodeBreakerViolationLocation(String voltageLevelId, List<String> busBarIds) {
Objects.requireNonNull(voltageLevelId, "voltageLevelId");
this.voltageLevelId = voltageLevelId;
this.busBarIds = busBarIds;
/**
* Create a ViolationLocation for a violation detected in a voltage level in node/breaker topology.
* @param voltageLevelId the id of the voltage level
* @param nodes The list of the nodes where the violation was detected.
*/
public NodeBreakerViolationLocation(String voltageLevelId, List<Integer> nodes) {
this.voltageLevelId = Objects.requireNonNull(voltageLevelId, "voltageLevelId should not be null");
this.nodes = Objects.requireNonNull(nodes, "nodes should not be null");
}

@Override
public String getVoltageLevelId() {
return voltageLevelId;
}

public List<Integer> getNodes() {
return nodes;
}

@Override
public List<String> getBusBarIds() {
return busBarIds;
public BusView getBusView(Network network) {
return () -> {
VoltageLevel vl = network.getVoltageLevel(voltageLevelId);
var busView = vl.getBusView();
return Networks.getNodesByBus(vl)
.entrySet()
.stream()
.filter(e -> nodes.stream().anyMatch(i -> e.getValue().contains(i)))
.map(e -> busView.getBus(e.getKey()))
.distinct();
};
}

@Override
public String getId() {
return busBarIds.isEmpty() ? voltageLevelId : busBarIds.get(0);
public BusView getBusBreakerView(Network network) {
throw new UnsupportedOperationException();
}

@Override
Expand All @@ -47,7 +67,7 @@ public Type getType() {
public String toString() {
return "NodeBreakerVoltageLocation{" +
"voltageLevelId='" + voltageLevelId + '\'' +
", busBarIds=" + busBarIds +
", nodes=" + nodes +
'}';
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@
*/
package com.powsybl.security;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import com.powsybl.iidm.network.Bus;
import com.powsybl.iidm.network.Network;

import java.util.stream.Stream;

/**
* @author Étienne Lesot {@literal <etienne.lesot at rte-france.com>}
Expand All @@ -21,18 +22,13 @@ enum Type {
BUS_BREAKER
}

String getId();

Type getType();

String getVoltageLevelId();
BusView getBusView(Network network);

default Optional<String> getBusId() {
return Optional.empty();
}
BusView getBusBreakerView(Network network);

default List<String> getBusBarIds() {
return Collections.emptyList();
interface BusView {
Stream<Bus> getBusStream();
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -78,15 +78,14 @@ public void checkApparentPower(ThreeWindingsTransformer transformer, ThreeSides
@Override
public void checkVoltage(Bus bus, double value, Consumer<LimitViolation> consumer) {
VoltageLevel vl = bus.getVoltageLevel();
ViolationLocation voltageViolationLocation = createViolationLocation(bus);
if (!Double.isNaN(vl.getLowVoltageLimit()) && value <= vl.getLowVoltageLimit()) {
consumer.accept(new LimitViolation(vl.getId(), vl.getOptionalName().orElse(null), LimitViolationType.LOW_VOLTAGE,
vl.getLowVoltageLimit(), limitReductionValue, value, voltageViolationLocation));
vl.getLowVoltageLimit(), limitReductionValue, value, createViolationLocation(bus)));
}

if (!Double.isNaN(vl.getHighVoltageLimit()) && value >= vl.getHighVoltageLimit()) {
consumer.accept(new LimitViolation(vl.getId(), vl.getOptionalName().orElse(null), LimitViolationType.HIGH_VOLTAGE,
vl.getHighVoltageLimit(), limitReductionValue, value, voltageViolationLocation));
vl.getHighVoltageLimit(), limitReductionValue, value, createViolationLocation(bus)));
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,9 @@
*/
public class ViolationLocationDeserializer extends StdDeserializer<ViolationLocation> {

private static final String BUS_ID = "busId";
private static final String BUS_IDS = "busIds";
private static final String VOLTAGE_LEVEL_ID = "voltageLevelId";
private static final String BUS_BAR_IDS = "busbarIds";
private static final String NODES = "nodes";

public ViolationLocationDeserializer() {
super(ViolationLocation.class);
Expand All @@ -36,35 +36,36 @@ public ViolationLocationDeserializer() {
@Override
public ViolationLocation deserialize(JsonParser parser, DeserializationContext deserializationContext) throws IOException {
String voltageLevelId = null;
String busId = null;
List<String> busbarIds = new ArrayList<>();
List<String> busIds = new ArrayList<>();
List<Integer> nodes = new ArrayList<>();
ViolationLocation.Type type = null;
while (parser.nextToken() != JsonToken.END_OBJECT) {
switch (parser.currentName()) {
case "type":
parser.nextToken();
type = JsonUtil.readValue(deserializationContext, parser, ViolationLocation.Type.class);
break;
case BUS_ID:
busId = parser.nextTextValue();
case BUS_IDS:
parser.nextToken();
busIds = JsonUtil.readList(deserializationContext, parser, String.class);
break;

case VOLTAGE_LEVEL_ID:
voltageLevelId = parser.nextTextValue();
break;

case BUS_BAR_IDS:
case NODES:
parser.nextToken();
busbarIds = JsonUtil.readList(deserializationContext, parser, String.class);
nodes = JsonUtil.readList(deserializationContext, parser, Integer.class);
break;
default:
throw new IllegalStateException("Unexpected field: " + parser.currentName());
}
}
if (type == ViolationLocation.Type.NODE_BREAKER) {
return new NodeBreakerViolationLocation(voltageLevelId, busbarIds);
return new NodeBreakerViolationLocation(voltageLevelId, nodes);
} else if (type == ViolationLocation.Type.BUS_BREAKER) {
return new BusBreakerViolationLocation(voltageLevelId, busId);
return new BusBreakerViolationLocation(busIds);
} else {
throw new IllegalStateException("type should be among [NODE_BREAKER, BUS_BREAKER].");
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,11 @@
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.powsybl.commons.json.JsonUtil;
import com.powsybl.security.BusBreakerViolationLocation;
import com.powsybl.security.NodeBreakerViolationLocation;
import com.powsybl.security.ViolationLocation;

import java.io.IOException;
import java.util.Optional;

/**
* @author Etienne Lesot {@literal <etienne.lesot at rte-france.com>}
Expand All @@ -29,13 +30,13 @@ public ViolationLocationSerializer() {
public void serialize(ViolationLocation violationLocation, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
JsonUtil.writeOptionalEnumField(jsonGenerator, "type", violationLocation.getType());
jsonGenerator.writeStringField("voltageLevelId", violationLocation.getVoltageLevelId());
Optional<String> busId = violationLocation.getBusId();
if (busId.isPresent()) {
jsonGenerator.writeStringField("busId", busId.get());
}
if (!violationLocation.getBusBarIds().isEmpty()) {
serializerProvider.defaultSerializeField("busbarIds", violationLocation.getBusBarIds(), jsonGenerator);
if (ViolationLocation.Type.NODE_BREAKER == violationLocation.getType()) {
NodeBreakerViolationLocation location = (NodeBreakerViolationLocation) violationLocation;
jsonGenerator.writeStringField("voltageLevelId", location.getVoltageLevelId());
serializerProvider.defaultSerializeField("nodes", location.getNodes(), jsonGenerator);
} else {
BusBreakerViolationLocation location = (BusBreakerViolationLocation) violationLocation;
serializerProvider.defaultSerializeField("busIds", location.getBusIds(), jsonGenerator);
}
jsonGenerator.writeEndObject();
}
Expand Down
Loading

0 comments on commit 8961560

Please sign in to comment.