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

Psse: full export to version 35 #3334

Draft
wants to merge 74 commits into
base: main
Choose a base branch
from
Draft
Changes from 1 commit
Commits
Show all changes
74 commits
Select commit Hold shift + click to select a range
b0c2d98
copy of the imported PSSE model to make the updates and export (deep …
marqueslanauja Mar 21, 2024
7947a24
Merge branch 'main' into psse_copy
marqueslanauja Mar 27, 2024
3d106ed
Merge branch 'main' into psse_copy
marqueslanauja Apr 10, 2024
362d13f
Import and update substation data
marqueslanauja Apr 11, 2024
5e93847
Remove duplicated code
marqueslanauja Apr 11, 2024
cab4aa1
Fix code smells
marqueslanauja Apr 11, 2024
67ff326
Fix code smells
marqueslanauja Apr 11, 2024
b39afef
nodeBreaker convert
marqueslanauja Apr 17, 2024
b74848e
Fix code smells
marqueslanauja Apr 17, 2024
e896564
Add tests. Last changes
marqueslanauja Apr 22, 2024
b2203bc
Fix code smells
marqueslanauja Apr 22, 2024
cff26cf
Merge branch 'main' into psse_nodeBreaker_convert
marqueslanauja Apr 22, 2024
0162bad
Merge branch 'main' into psse_nodeBreaker_convert
marqueslanauja Apr 23, 2024
57362ce
Merge branch 'main' into psse_nodeBreaker_convert
marqueslanauja Apr 25, 2024
8ad9c73
Merge branch 'main' into psse_nodeBreaker_convert
marqueslanauja May 2, 2024
decd4b8
Merge branch 'main' into psse_nodeBreaker_convert
marqueslanauja Jun 3, 2024
786bc59
Merge branch 'main' into psse_nodeBreaker_convert
marqueslanauja Jun 3, 2024
1f71051
full export. First version
marqueslanauja Jun 17, 2024
47f2df2
Minor changes in ContextExport
marqueslanauja Jun 17, 2024
5aeb31d
Reorganize code
marqueslanauja Jun 17, 2024
3dd3d88
Minor changes
marqueslanauja Jun 17, 2024
c424ea2
LoadConvert
marqueslanauja Jun 17, 2024
2e5d7a1
Bus converter
marqueslanauja Jun 17, 2024
244f71e
Create fixedShunts
marqueslanauja Jun 18, 2024
e8667b1
Fixed Shunt. Define fieldNames
marqueslanauja Jun 18, 2024
470846e
create generators
marqueslanauja Jun 18, 2024
4c2e4ae
Create Lines
marqueslanauja Jun 19, 2024
f27b818
Clean code
marqueslanauja Jun 19, 2024
d1a9f96
Full export. Transformers
marqueslanauja Jul 16, 2024
d765d7c
Full export. Lines: findRates
marqueslanauja Jul 16, 2024
b609246
Pretty code
marqueslanauja Jul 17, 2024
138727f
Full export. Switched shunts
marqueslanauja Jul 17, 2024
806615c
Fix replaceAll errors
marqueslanauja Jul 17, 2024
7d8985b
Full export. Lcc hvdc lines
marqueslanauja Jul 17, 2024
517e050
Import VscDcTransmissionLine
marqueslanauja Jul 19, 2024
0abb30c
Deep copy for TwoTerminalDc and VscDcTransmissionLine
marqueslanauja Jul 19, 2024
8adce09
Full export: vscDcTransmissionLine
marqueslanauja Aug 1, 2024
fa0936c
Merge branch 'main' into psse_full_export
marqueslanauja Aug 9, 2024
299568d
Adjustments after importing a private real case
marqueslanauja Aug 9, 2024
47639c1
Merge branch 'main' into psse_full_export
marqueslanauja Sep 3, 2024
f5cfe74
Update full export considering a bus as all the nodes connected by sw…
marqueslanauja Sep 10, 2024
ac78cae
Some improvements
marqueslanauja Sep 10, 2024
03e54d9
FactsDevices convert
marqueslanauja Sep 12, 2024
bde67af
create default methods for all converters
marqueslanauja Sep 13, 2024
e22b79f
FullExport: FactsDevices
marqueslanauja Sep 13, 2024
68ac48d
Create TieLines
marqueslanauja Sep 16, 2024
a35700c
TieLine minor changes
marqueslanauja Sep 16, 2024
179c7b7
FullExport: batteries
marqueslanauja Sep 18, 2024
97636a2
Full Export: DanglingLines
marqueslanauja Sep 18, 2024
74afe02
Improvements
marqueslanauja Jan 2, 2025
c1bf28b
Fix issues
marqueslanauja Jan 2, 2025
32a178b
Comment clarification
marqueslanauja Jan 7, 2025
1ef0dda
Merge branch 'main' into psse_nodeBreaker_convert_improvements
marqueslanauja Jan 7, 2025
02ddcf5
Merge branch 'main' into psse_nodeBreaker_convert_improvements
marqueslanauja Feb 25, 2025
84549bb
Merge branch 'main' into psse_nodeBreaker_convert_improvements
marqueslanauja Feb 25, 2025
4187dec
Minor change
marqueslanauja Feb 25, 2025
c4232fe
Merge branch 'psse_nodeBreaker_convert_improvements' into psse_full_e…
marqueslanauja Feb 26, 2025
4c929c1
Merge branch 'main' into psse_full_export
marqueslanauja Feb 26, 2025
025290a
Pretty code
marqueslanauja Feb 26, 2025
a14f29b
Copy PsseFacts
marqueslanauja Feb 26, 2025
13766d6
Fix issues
marqueslanauja Feb 26, 2025
404286c
Fix issues
marqueslanauja Feb 26, 2025
ccf6b95
Fix issues
marqueslanauja Feb 26, 2025
52a9ed6
Fix issue
marqueslanauja Feb 26, 2025
fd93a2d
Reduce the complexity
marqueslanauja Feb 26, 2025
dc954de
Final tests and improvements
marqueslanauja Mar 6, 2025
43a5af5
Merge branch 'main' into psse_full_export
marqueslanauja Mar 10, 2025
b712452
Fix issues
marqueslanauja Mar 10, 2025
d80434d
extend badly connected equipment and badly defined controlled buses t…
marqueslanauja Mar 10, 2025
69787ea
add more unit tests
marqueslanauja Mar 10, 2025
405ceae
Improve unit tests
marqueslanauja Mar 10, 2025
f37fe4b
Merge branch 'main' into psse_full_export
marqueslanauja Mar 10, 2025
f1a3da2
Merge branch 'main' into psse_full_export
marqueslanauja Mar 18, 2025
55d50f0
Merge branch 'main' into psse_full_export
zamarrenolm Mar 20, 2025
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
Prev Previous commit
Next Next commit
Add tests. Last changes
Signed-off-by: José Antonio Marqués <[email protected]>
marqueslanauja committed Apr 22, 2024
commit e896564f4d164e019a0a4f939fbd1f1e46e0ca1f
Original file line number Diff line number Diff line change
@@ -13,6 +13,7 @@
import java.util.Set;

import com.powsybl.iidm.network.Terminal;
import com.powsybl.iidm.network.TopologyKind;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.iidm.network.util.Networks;
import com.powsybl.psse.model.PsseException;
@@ -34,7 +35,7 @@ enum PsseEquipmentType {
PSSE_BRANCH("B"),
PSSE_TWO_WINDING("2"),
PSSE_THREE_WINDING("3"),
PSSE_SWITCHED_SHUNT("s"),
PSSE_SWITCHED_SHUNT("S"),
PSSE_INDUCTION_MACHINE("I"),
PSSE_TWO_TERMINAL_DC_LINE("D"),
PSSE_VSC_DC_LINE("V"),
@@ -47,7 +48,7 @@ enum PsseEquipmentType {
this.textCode = textCode;
}

private String getTextCode() {
String getTextCode() {
return textCode;
}
}
@@ -90,7 +91,7 @@ static String getNodeBreakerEquipmentId(String type, int busI, int busJ, int bus
} else if (bus1 == 0) {
return type + "." + bus2 + "." + bus3 + "." + id;
} else {
return type + "." + bus1 + "." + bus2 + "." + "." + bus3 + id;
return type + "." + bus1 + "." + bus2 + "." + bus3 + "." + id;
}
}

@@ -117,6 +118,19 @@ static int obtainBus(NodeBreakerExport nodeBreakerExport, String equipmentId, in
return nodeBreakerExport.getEquipmentIdBusBus(getNodeBreakerEquipmentIdBus(equipmentId, bus)).orElseGet(() -> bus);
}

// the psse control node always is identical to the iidm node (not affected by internal connections)
static int obtainRegulatingBus(NodeBreakerExport nodeBreakerExport, Terminal regulatingTerminal, int bus) {
if (regulatingTerminal == null) {
return bus;
}
if (regulatingTerminal.getVoltageLevel().getTopologyKind().equals(TopologyKind.BUS_BREAKER)) {
return bus;
}
String voltageLevelId = regulatingTerminal.getVoltageLevel().getId();
int node = regulatingTerminal.getNodeBreakerView().getNode();
return nodeBreakerExport.getNodeBus(voltageLevelId, node).orElseGet(() -> bus);
}

static Terminal obtainTerminalNode(Network network, String voltageLevelId, int node) {
VoltageLevel voltageLevel = network.getVoltageLevel(voltageLevelId);
return voltageLevel != null ? obtainTerminalNode(voltageLevel, node) : null;
Original file line number Diff line number Diff line change
@@ -63,18 +63,25 @@ static void updateBuses(Network network, PssePowerFlowModel psseModel, NodeBreak

// create new psse buses
List<PsseBus> addedBuses = new ArrayList<>();
nodeBreakerExport.getNewBusesSet().stream().sorted().forEach(newBus -> {
int copyBus = nodeBreakerExport.getNewBusCopyBus(newBus).orElseThrow();
String busBreakerId = nodeBreakerExport.getNewBusBusBreakerId(newBus).orElseThrow();
int type = nodeBreakerExport.getNewBusType(newBus).orElseThrow();
nodeBreakerExport.getNewMappedBusesSet().stream().sorted().forEach(newBus -> {
int copyBus = nodeBreakerExport.getNewMappedBusCopyBus(newBus).orElseThrow();
String busBreakerId = nodeBreakerExport.getNewMappedBusBusBreakerId(newBus).orElse(null);
int type = nodeBreakerExport.getNewMappedBusType(newBus).orElseThrow();

PsseBus psseBus = createNewBus(copyBus, newBus, busNumToPsseBus);
updatePsseBus(network, busBreakerId, psseBus, type);
addedBuses.add(psseBus);
});

nodeBreakerExport.getNewNotMappedBusesSet().stream().sorted().forEach(newBus -> {
int copyBus = nodeBreakerExport.getNewNotMappedBusCopyBus(newBus).orElseThrow();

PsseBus psseBus = createNewBus(copyBus, newBus, busNumToPsseBus);
updateIsolatedPsseBus(psseBus);
addedBuses.add(psseBus);
});

psseModel.addBuses(addedBuses);
psseModel.addBuses(addedBuses.stream().sorted(Comparator.comparingInt(psseBus -> psseBus.getI())).toList());
}

private static PsseBus createNewBus(int copyBus, int newBus, Map<Integer, PsseBus> busNumToPsseBus) {
@@ -105,19 +112,23 @@ private static PsseBus obtainPsseBus(int bus, Map<Integer, PsseBus> busNumToPsse
}
}

private static void updatePsseBus(Network network, String busId, PsseBus psseBus, int type) {
Bus bus = network.getBusBreakerView().getBus(busId);
private static void updatePsseBus(Network network, String busBreakerId, PsseBus psseBus, int type) {
Bus bus = network.getBusBreakerView().getBus(busBreakerId);
if (bus == null) {
psseBus.setVm(0.0);
psseBus.setVa(0.0);
psseBus.setIde(4);
updateIsolatedPsseBus(psseBus);
} else {
psseBus.setVm(getVm(bus));
psseBus.setVa(getVa(bus));
psseBus.setIde(type);
}
}

private static void updateIsolatedPsseBus(PsseBus psseBus) {
psseBus.setVm(0.0);
psseBus.setVa(0.0);
psseBus.setIde(4);
}

private static double getVm(Bus bus) {
return Double.isFinite(bus.getV()) && bus.getV() > 0.0 ? bus.getV() / bus.getVoltageLevel().getNominalV() : 1.0;
}
Original file line number Diff line number Diff line change
@@ -141,6 +141,7 @@ static void updateGenerators(Network network, PssePowerFlowModel psseModel, Node
String genId = getGeneratorId(getBusId(psseGen.getI()), psseGen.getId());
Generator gen = network.getGenerator(genId);
int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_GENERATOR, psseGen.getI(), psseGen.getId()), psseGen.getI());
int regulatingBus = obtainRegulatingBus(nodeBreakerExport, gen.getRegulatingTerminal(), psseGen.getIreg());

if (gen == null) {
psseGen.setStat(0);
@@ -150,9 +151,17 @@ static void updateGenerators(Network network, PssePowerFlowModel psseModel, Node
psseGen.setQg(getQ(gen));
}
psseGen.setI(bus);
if (regulatingBusMustBeChanged(bus, regulatingBus, psseGen.getIreg())) {
psseGen.setIreg(regulatingBus);
}
});
}

// zero can be used for local regulation
private static boolean regulatingBusMustBeChanged(int bus, int newRegulatingBus, int regulatingBus) {
return !(bus == newRegulatingBus && regulatingBus == 0);
}

private static int getStatus(Generator gen) {
if (gen.getTerminal().isConnected() && gen.getTerminal().getBusBreakerView().getBus() != null) {
return 1;
Original file line number Diff line number Diff line change
@@ -17,15 +17,17 @@
*/
final class NodeBreakerExport {
private int maxPsseBus;
private final Map<Integer, NodeBreakerNewBus> newBuses;
private final Map<Integer, NodeBreakerNewBus> newMappedBuses; // New buses mapped to iidm buses
private final Map<Integer, Integer> newNotMappedBuses; // New buses not mapped to iidm buses
private final Map<Integer, Pair<String, Integer>> buses;
private final Set<Integer> isolatedBuses;
private final Map<String, Pair<Integer, Boolean>> nodeBus;
private final Map<String, Integer> equipmentIdBusBus;

NodeBreakerExport(int maxPsseBus) {
this.maxPsseBus = maxPsseBus;
this.newBuses = new HashMap<>();
this.newMappedBuses = new HashMap<>();
this.newNotMappedBuses = new HashMap<>();
this.buses = new HashMap<>();
this.isolatedBuses = new HashSet<>();
this.nodeBus = new HashMap<>();
@@ -36,24 +38,37 @@ int getNewPsseBus() {
return ++maxPsseBus;
}

void addNewBus(int newBus, int copyBus, String busBreakerBusId, int type) {
newBuses.put(newBus, new NodeBreakerNewBus(copyBus, busBreakerBusId, type));
void addNewMappedBus(int newBus, int copyBus, String busBreakerBusId, int type) {
newMappedBuses.put(newBus, new NodeBreakerNewBus(copyBus, busBreakerBusId, type));
}

Set<Integer> getNewBusesSet() {
return newBuses.keySet();
void addNewNotMappedBus(int newBus, int copyBus) {
newNotMappedBuses.put(newBus, copyBus);
}

OptionalInt getNewBusCopyBus(int newBus) {
return newBuses.containsKey(newBus) ? OptionalInt.of(newBuses.get(newBus).busCopy) : OptionalInt.empty();
Set<Integer> getNewMappedBusesSet() {
return newMappedBuses.keySet();
}

Optional<String> getNewBusBusBreakerId(int newBus) {
return newBuses.containsKey(newBus) ? Optional.of(newBuses.get(newBus).busBreakerId) : Optional.empty();
OptionalInt getNewMappedBusCopyBus(int newBus) {
return newMappedBuses.containsKey(newBus) ? OptionalInt.of(newMappedBuses.get(newBus).busCopy) : OptionalInt.empty();
}

OptionalInt getNewBusType(int newBus) {
return newBuses.containsKey(newBus) ? OptionalInt.of(newBuses.get(newBus).type) : OptionalInt.empty();
Optional<String> getNewMappedBusBusBreakerId(int newBus) {
// New Isolated buses do not have busBreakerId. Null is considered
return newMappedBuses.containsKey(newBus) ? Optional.ofNullable(newMappedBuses.get(newBus).busBreakerId) : Optional.empty();
}

OptionalInt getNewMappedBusType(int newBus) {
return newMappedBuses.containsKey(newBus) ? OptionalInt.of(newMappedBuses.get(newBus).type) : OptionalInt.empty();
}

Set<Integer> getNewNotMappedBusesSet() {
return newNotMappedBuses.keySet();
}

OptionalInt getNewNotMappedBusCopyBus(int newBus) {
return newNotMappedBuses.containsKey(newBus) ? OptionalInt.of(newNotMappedBuses.get(newBus)) : OptionalInt.empty();
}

void addBusMapping(int bus, String busBreakerBusId, int type) {
Original file line number Diff line number Diff line change
@@ -131,6 +131,7 @@ private static void updateModifiedBlocks(Network network, PssePowerFlowModel upd
GeneratorConverter.updateGenerators(network, updatedPsseModel, nodeBreakerExport);
LineConverter.updateLines(network, updatedPsseModel, nodeBreakerExport);
TransformerConverter.updateTransformers(network, updatedPsseModel, nodeBreakerExport);
TwoTerminalDcConverter.updateTwoTerminalDcTransmissionLines(network, updatedPsseModel, nodeBreakerExport);
SwitchedShuntCompensatorConverter.updateSwitchedShunts(network, updatedPsseModel, nodeBreakerExport);
}
}
Original file line number Diff line number Diff line change
@@ -10,6 +10,7 @@
import com.powsybl.iidm.network.Bus;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.Terminal;
import com.powsybl.iidm.network.VoltageLevel;
import com.powsybl.iidm.network.extensions.SlackTerminal;
import com.powsybl.iidm.network.util.ContainersMapping;
import com.powsybl.iidm.network.util.TerminalFinder;
@@ -32,22 +33,24 @@ class SlackConverter extends AbstractConverter {
}

void create() {
for (PsseBus psseBus : psseBusList) {
if (psseBus.getIde() == 3) {
Bus bus;
Optional<NodeBreakerImport.NodeBreakerControlNode> slackControlNode = nodeBreakerImport.getSlackControlNode(psseBus.getI());
if (slackControlNode.isPresent()) {
Terminal terminal = obtainTerminalNode(getNetwork(), slackControlNode.get().getVoltageLevelId(), slackControlNode.get().getNode());
bus = terminal != null ? terminal.getBusBreakerView().getBus() : null;
} else {
String busId = AbstractConverter.getBusId(psseBus.getI());
bus = getNetwork().getBusBreakerView().getBus(busId);
psseBusList.stream().filter(psseBus -> psseBus.getIde() == 3).forEach(psseBus -> {

Optional<NodeBreakerImport.NodeBreakerControlNode> slackControlNode = nodeBreakerImport.getSlackControlNode(psseBus.getI());
if (slackControlNode.isPresent()) {
Terminal terminal = obtainTerminalNode(getNetwork(), slackControlNode.get().getVoltageLevelId(), slackControlNode.get().getNode());
VoltageLevel voltageLevel = getNetwork().getVoltageLevel(slackControlNode.get().getVoltageLevelId());

if (voltageLevel != null && terminal != null) {
SlackTerminal.reset(voltageLevel, terminal);
}
} else {
String busId = AbstractConverter.getBusId(psseBus.getI());
Bus bus = getNetwork().getBusBreakerView().getBus(busId);
if (slackBusIsValidForIidm(bus)) {
SlackTerminal.attach(bus);
}
}
}
});
}

private static boolean slackBusIsValidForIidm(Bus bus) {
Original file line number Diff line number Diff line change
@@ -143,6 +143,14 @@ private static int switchedShuntRegulatingBus(PsseSwitchedShunt switchedShunt, P
}
}

private static void setSwitchedShuntRegulatingBus(PsseSwitchedShunt switchedShunt, PsseVersion psseVersion, int regulatingBus) {
if (psseVersion.major() == V35) {
switchedShunt.setSwreg(regulatingBus);
} else {
switchedShunt.setSwrem(regulatingBus);
}
}

private static int defineSectionCount(double binit, List<ShuntBlock> shuntBlocks) {
double maxDistance = Double.MAX_VALUE;
int sectionCount = 0;
@@ -283,13 +291,15 @@ static void updateSwitchedShunts(Network network, PssePowerFlowModel psseModel,
String switchedShuntId = getShuntId(getBusId(psseSwitchedShunt.getI()), defineShuntId(psseSwitchedShunt, version));
ShuntCompensator switchedShunt = network.getShuntCompensator(switchedShuntId);
int bus = obtainBus(nodeBreakerExport, getNodeBreakerEquipmentId(PSSE_SWITCHED_SHUNT, psseSwitchedShunt.getI(), defineShuntId(psseSwitchedShunt, version)), psseSwitchedShunt.getI());
int regulatingBus = obtainRegulatingBus(nodeBreakerExport, switchedShunt.getRegulatingTerminal(), switchedShuntRegulatingBus(psseSwitchedShunt, version));
if (switchedShunt == null) {
psseSwitchedShunt.setStat(0);
} else {
psseSwitchedShunt.setStat(getStatus(switchedShunt));
psseSwitchedShunt.setBinit(getQ(switchedShunt));
}
psseSwitchedShunt.setI(bus);
setSwitchedShuntRegulatingBus(psseSwitchedShunt, version, regulatingBus);
});
}

Original file line number Diff line number Diff line change
@@ -16,6 +16,7 @@
import org.slf4j.LoggerFactory;

import com.powsybl.iidm.network.ThreeWindingsTransformer.Leg;
import com.powsybl.iidm.network.RatioTapChanger;
import com.powsybl.iidm.network.util.ContainersMapping;
import com.powsybl.psse.converter.PsseImporter.PerUnitContext;
import com.powsybl.psse.model.PsseException;
@@ -24,8 +25,8 @@
import com.powsybl.psse.model.pf.PssePowerFlowModel;
import com.powsybl.psse.model.pf.PsseTransformer;
import com.powsybl.psse.model.pf.PsseTransformerWinding;
import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_TWO_WINDING;
import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.PSSE_THREE_WINDING;

import static com.powsybl.psse.converter.AbstractConverter.PsseEquipmentType.*;
import static com.powsybl.psse.model.PsseVersion.Major.V35;

/**
@@ -726,7 +727,7 @@ private static boolean isTwoWindingsTransformer(PsseTransformer psseTransformer)

private void addControlTwoWindingsTransformer() {
String id = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt());
String equipmentId = "";
String equipmentId = getNodeBreakerEquipmentId(PSSE_TWO_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getCkt());
TwoWindingsTransformer twt = getNetwork().getTwoWindingsTransformer(id);
if (twt == null) {
return;
@@ -743,7 +744,7 @@ private void addControlTwoWindingsTransformer() {

private void addControlThreeWindingsTransformer() {
String id = getTransformerId(psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt());
String equipmentId = "";
String equipmentId = getNodeBreakerEquipmentId(PSSE_THREE_WINDING, psseTransformer.getI(), psseTransformer.getJ(), psseTransformer.getK(), psseTransformer.getCkt());
ThreeWindingsTransformer twt = getNetwork().getThreeWindingsTransformer(id);
if (twt == null) {
return;
@@ -896,11 +897,21 @@ private static void updateTwoWindingsTransformer(Network network, PsseTransforme
int busJ = obtainBus(nodeBreakerExport, equipmentId, psseTransformer.getJ());
psseTransformer.setI(busI);
psseTransformer.setJ(busJ);
int regulatingBus = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw2t), psseTransformer.getWinding1().getCont());
psseTransformer.getWinding1().setCont(regulatingBus);

psseTransformer.setStat(getStatus(tw2t));
}
}

private static Terminal obtainRegulatingTerminal(TwoWindingsTransformer tw2t) {
Terminal regulatingTerminal = tw2t.getOptionalRatioTapChanger().map(RatioTapChanger::getRegulationTerminal).orElse(null);
if (regulatingTerminal != null) {
return regulatingTerminal;
}
return tw2t.getOptionalPhaseTapChanger().map(PhaseTapChanger::getRegulationTerminal).orElse(null);
}

private static int getStatus(TwoWindingsTransformer tw2t) {
if (tw2t.getTerminal1().isConnected() && tw2t.getTerminal1().getBusBreakerView().getBus() != null
&& tw2t.getTerminal2().isConnected() && tw2t.getTerminal2().getBusBreakerView().getBus() != null) {
@@ -939,10 +950,25 @@ private static void updateThreeWindingsTransformer(Network network, PsseTransfor
psseTransformer.setJ(busJ);
psseTransformer.setK(busK);

int regulatingBus1 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg1()), psseTransformer.getWinding1().getCont());
int regulatingBus2 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg2()), psseTransformer.getWinding2().getCont());
int regulatingBus3 = obtainRegulatingBus(nodeBreakerExport, obtainRegulatingTerminal(tw3t.getLeg3()), psseTransformer.getWinding3().getCont());
psseTransformer.getWinding1().setCont(regulatingBus1);
psseTransformer.getWinding2().setCont(regulatingBus2);
psseTransformer.getWinding3().setCont(regulatingBus3);

psseTransformer.setStat(getStatus(tw3t));
}
}

private static Terminal obtainRegulatingTerminal(Leg leg) {
Terminal regulatingTerminal = leg.getOptionalRatioTapChanger().map(RatioTapChanger::getRegulationTerminal).orElse(null);
if (regulatingTerminal != null) {
return regulatingTerminal;
}
return leg.getOptionalPhaseTapChanger().map(PhaseTapChanger::getRegulationTerminal).orElse(null);
}

private static int getStatus(ThreeWindingsTransformer tw3t) {
if (tw3t.getLeg1().getTerminal().isConnected() && tw3t.getLeg1().getTerminal().getBusBreakerView().getBus() != null
&& tw3t.getLeg2().getTerminal().isConnected() && tw3t.getLeg2().getTerminal().getBusBreakerView().getBus() != null
Loading