|
8 | 8 |
|
9 | 9 | import com.powsybl.iidm.network.IdentifiableType;
|
10 | 10 | import com.powsybl.iidm.network.Switch;
|
| 11 | +import com.powsybl.iidm.network.SwitchKind; |
11 | 12 | import com.powsybl.iidm.network.Terminal;
|
12 | 13 | import com.powsybl.math.graph.TraverseResult;
|
| 14 | +import lombok.Getter; |
| 15 | + |
| 16 | +import java.util.ArrayList; |
| 17 | +import java.util.HashSet; |
| 18 | +import java.util.List; |
| 19 | +import java.util.Set; |
13 | 20 |
|
14 | 21 | /**
|
15 | 22 | * @author Slimane Amar <slimane.amar at rte-france.com>
|
16 | 23 | */
|
17 | 24 | public class BusbarSectionFinderTraverser implements Terminal.TopologyTraverser {
|
18 | 25 |
|
19 |
| - private final boolean onlyConnectedBbs; |
20 |
| - |
21 |
| - private String firstTraversedBbsId; |
22 |
| - |
23 |
| - public BusbarSectionFinderTraverser(boolean onlyConnectedBbs) { |
24 |
| - this.onlyConnectedBbs = onlyConnectedBbs; |
25 |
| - } |
| 26 | + private final List<BusbarCandidate> busbarCandidates = new ArrayList<>(); |
| 27 | + private final Set<String> visitedTerminals = new HashSet<>(); |
| 28 | + private static final int MAX_VISITED = 50; |
26 | 29 |
|
27 | 30 | @Override
|
28 | 31 | public TraverseResult traverse(Terminal terminal, boolean connected) {
|
29 |
| - if (terminal.getConnectable().getType() == IdentifiableType.BUSBAR_SECTION) { |
30 |
| - firstTraversedBbsId = terminal.getConnectable().getId(); |
| 32 | + String terminalId = terminal.getConnectable().getId(); |
| 33 | + if (visitedTerminals.contains(terminalId)) { |
| 34 | + return TraverseResult.TERMINATE_PATH; |
| 35 | + } |
| 36 | + visitedTerminals.add(terminalId); |
| 37 | + if (visitedTerminals.size() > MAX_VISITED) { |
31 | 38 | return TraverseResult.TERMINATE_TRAVERSER;
|
32 | 39 | }
|
| 40 | + |
| 41 | + // If a busbar section is found, add it as a candidate |
| 42 | + if (terminal.getConnectable().getType() == IdentifiableType.BUSBAR_SECTION) { |
| 43 | + busbarCandidates.add(new BusbarCandidate(terminalId, connected)); |
| 44 | + // CONTINUE to explore other paths to other busbars |
| 45 | + return TraverseResult.CONTINUE; |
| 46 | + } |
33 | 47 | return TraverseResult.CONTINUE;
|
34 | 48 | }
|
35 | 49 |
|
36 | 50 | @Override
|
37 | 51 | public TraverseResult traverse(Switch aSwitch) {
|
38 |
| - if (onlyConnectedBbs && aSwitch.isOpen()) { |
39 |
| - return TraverseResult.TERMINATE_PATH; |
| 52 | + if (visitedTerminals.size() > MAX_VISITED) { |
| 53 | + return TraverseResult.TERMINATE_TRAVERSER; |
| 54 | + } |
| 55 | + |
| 56 | + // KEY: Open disconnectors end this path but not the overall traversal |
| 57 | + // They block access to this busbar but not to the others |
| 58 | + if (aSwitch.isOpen() && aSwitch.getKind() == SwitchKind.DISCONNECTOR) { |
| 59 | + return TraverseResult.TERMINATE_PATH; // Ends this path, not the whole traversal |
40 | 60 | }
|
41 | 61 | return TraverseResult.CONTINUE;
|
42 | 62 | }
|
43 | 63 |
|
44 |
| - public String getFirstTraversedBbsId() { |
45 |
| - return firstTraversedBbsId; |
| 64 | + public String getBusbarWithClosedDisconnector() { |
| 65 | + // Search for a connected busbar (disconnector closed) |
| 66 | + for (BusbarCandidate candidate : busbarCandidates) { |
| 67 | + if (candidate.isConnected()) { |
| 68 | + return candidate.getId(); |
| 69 | + } |
| 70 | + } |
| 71 | + |
| 72 | + // If none is connected, return the first one found (fallback) |
| 73 | + if (!busbarCandidates.isEmpty()) { |
| 74 | + return busbarCandidates.getFirst().getId(); |
| 75 | + } |
| 76 | + return null; |
| 77 | + } |
| 78 | + |
| 79 | + @Getter |
| 80 | + private static class BusbarCandidate { |
| 81 | + private final String id; |
| 82 | + private final boolean connected; |
| 83 | + |
| 84 | + public BusbarCandidate(String id, boolean connected) { |
| 85 | + this.id = id; |
| 86 | + this.connected = connected; |
| 87 | + } |
46 | 88 | }
|
47 | 89 | }
|
0 commit comments