SwitchConversion.java
/**
* Copyright (c) 2017-2018, 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.cgmes.conversion.elements;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.iidm.network.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.powsybl.cgmes.conversion.Context;
import com.powsybl.cgmes.conversion.ConversionException;
import com.powsybl.triplestore.api.PropertyBag;
import java.util.Optional;
/**
* @author Luma Zamarre��o {@literal <zamarrenolm at aia.es>}
*/
public class SwitchConversion extends AbstractConductingEquipmentConversion implements EquipmentAtBoundaryConversion {
private DanglingLine danglingLine;
public SwitchConversion(PropertyBag sw, Context context) {
super(CgmesNames.SWITCH, sw, context, 2);
}
@Override
public boolean valid() {
// super.valid checks nodes and voltage levels of all terminals
// We may encounter boundary switches that do not have voltage level at boundary terminal
// So we check only that we have valid nodes
if (!validNodes()) {
return false;
}
if (busId(1).equals(busId(2))) {
ignored("end buses are the same bus " + busId(1));
return false;
}
if ((isBoundary(1) || isBoundary(2)) && LOG.isWarnEnabled()) {
LOG.warn("Switch {} has at least one end in the boundary", id);
LOG.warn(" busId1, voltageLevel1 : {} {}", busId(1), voltageLevel(1).orElse(null));
LOG.warn(" side 1 is boundary : {}", isBoundary(1));
LOG.warn(" busId2, voltageLevel2 : {} {}", busId(2), voltageLevel(2).orElse(null));
LOG.warn(" side 2 is boundary : {}", isBoundary(2));
}
return true;
}
@Override
public void convert() {
convertToSwitch();
}
@Override
public void convertAtBoundary() {
if (isBoundary(1)) {
convertSwitchAtBoundary(1);
} else if (isBoundary(2)) {
convertSwitchAtBoundary(2);
} else {
throw new ConversionException("Boundary must be at one end of the switch");
}
}
@Override
public Optional<DanglingLine> getDanglingLine() {
return Optional.ofNullable(danglingLine);
}
private Switch convertToSwitch() {
boolean normalOpen = p.asBoolean("normalOpen", false);
boolean open = p.asBoolean("open", normalOpen);
Switch s;
if (context.nodeBreaker()) {
VoltageLevel.NodeBreakerView.SwitchAdder adder = voltageLevel().getNodeBreakerView().newSwitch().setKind(kind());
identify(adder);
connect(adder, open);
boolean retained = p.asBoolean("retained", false);
adder.setRetained(retained);
s = adder.add();
if (!kindHasDirectMapToIiidm()) {
addTypeAsProperty(s);
}
} else {
VoltageLevel.BusBreakerView.SwitchAdder adder = voltageLevel().getBusBreakerView().newSwitch();
identify(adder);
connect(adder, open);
s = adder.add();
// Always preserve the original type, because all switches at bus/breaker view will be of kind "breaker"
addTypeAsProperty(s);
}
addAliasesAndProperties(s);
return s;
}
private void convertSwitchAtBoundary(int boundarySide) {
if (context.config().convertBoundary()) {
convertToSwitch().setRetained(true);
} else {
warnDanglingLineCreated();
String eqInstance = p.get("graph");
danglingLine = convertToDanglingLine(eqInstance, boundarySide);
}
}
private SwitchKind kind() {
String type = p.getLocal("type");
return switch (type) {
case "Disconnector", "GroundDisconnector", "Jumper" -> SwitchKind.DISCONNECTOR;
case "LoadBreakSwitch" -> SwitchKind.LOAD_BREAK_SWITCH;
default -> SwitchKind.BREAKER; // Breaker, Switch, ProtectedSwitch
};
}
private boolean kindHasDirectMapToIiidm() {
String type = p.getLocal("type");
return type.equals("Breaker") || type.equals("Disconnector") || type.equals("LoadBreakSwitch");
}
private void addTypeAsProperty(Switch s) {
s.setProperty(Conversion.PROPERTY_CGMES_ORIGINAL_CLASS, p.getLocal("type"));
}
private void warnDanglingLineCreated() {
fixed("Dangling line with low impedance", "Connected to a boundary node");
}
private static final Logger LOG = LoggerFactory.getLogger(SwitchConversion.class);
}