diff --git a/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java b/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java index 17b2d837d..add659c09 100644 --- a/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java +++ b/diagram-test/src/main/java/com/powsybl/diagram/test/Networks.java @@ -1205,6 +1205,9 @@ private static void createStatusExtensions(Network network) { network.getTwoWindingsTransformer("T12").newExtension(OperatingStatusAdder.class).withStatus(OperatingStatus.Status.FORCED_OUTAGE).add(); network.getThreeWindingsTransformer(THREE_WINDING_TRANSFORMER_12_ID).newExtension(OperatingStatusAdder.class).withStatus(OperatingStatus.Status.FORCED_OUTAGE).add(); + if (network.getVoltageLevel("VL2").getTopologyKind() == TopologyKind.NODE_BREAKER) { + network.getBusbarSection("BBS2").newExtension(OperatingStatusAdder.class).withStatus(OperatingStatus.Status.FORCED_OUTAGE).add(); + } } public static Network createNodeBreakerNetworkWithInternalBranches(String id, String sourceFormat) { @@ -1672,6 +1675,12 @@ public static Network createNetworkWithInternalPst() { return network; } + public static Network createNetworkWithInternalPstAndBranchStatus() { + Network network = createNetworkWithInternalPst(); + network.getTwoWindingsTransformer("trf3").newExtension(OperatingStatusAdder.class).withStatus(OperatingStatus.Status.FORCED_OUTAGE).add(); + return network; + } + public static Network createNetworkWithFlatSections() { Network network = Network.create("TestSingleLineDiagramClass", "test"); Substation substation = createSubstation(network, "s", "s", Country.FR); diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/AbstractLabelProvider.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/AbstractLabelProvider.java index b37d996fc..a543abdd0 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/AbstractLabelProvider.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/AbstractLabelProvider.java @@ -11,6 +11,7 @@ import com.powsybl.sld.layout.LayoutParameters; import com.powsybl.sld.library.ComponentLibrary; import com.powsybl.sld.model.coordinate.Direction; +import com.powsybl.sld.model.coordinate.Orientation; import com.powsybl.sld.model.coordinate.Side; import com.powsybl.sld.model.graphs.VoltageLevelGraph; import com.powsybl.sld.model.nodes.*; @@ -95,6 +96,10 @@ protected LabelPosition getMiddle3WTDecoratorPosition(Middle3WTNode node, Direct 0, yShift, true, 0); } + protected LabelPosition getBusDecoratorPosition() { + return new LabelPosition("BUS_DECORATOR", 35, -10, true, 0); + } + protected LabelPosition getLabelPosition(Node node, Direction direction) { double yShift = -LABEL_OFFSET; String positionName = ""; @@ -113,6 +118,18 @@ protected LabelPosition getLabelPosition(Node node, Direction direction) { svgParameters.isLabelCentered() ? 0 : -LABEL_OFFSET, yShift, svgParameters.isLabelCentered(), (int) angle); } + protected LabelPosition getInternal2WTDecoratorPosition(Orientation orientation) { + if (orientation.isHorizontal()) { + return new LabelPosition("INTERNAL_2WT_DECORATOR", 0, -15, true, 0); + } else { + return new LabelPosition("INTERNAL_2WT_DECORATOR", 15, 0, true, 0); + } + } + + protected LabelPosition getGenericDecoratorPosition() { + return new LabelPosition("GENERIC_DECORATOR", 0, 0, true, 0); + } + protected LabelPosition getBusLabelPosition() { return new LabelPosition("NW_LABEL", -LABEL_OFFSET, -LABEL_OFFSET, false, 0); } diff --git a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/DefaultLabelProvider.java b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/DefaultLabelProvider.java index 4bbb9aeb9..7e83eb4e5 100644 --- a/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/DefaultLabelProvider.java +++ b/single-line-diagram/single-line-diagram-core/src/main/java/com/powsybl/sld/svg/DefaultLabelProvider.java @@ -168,18 +168,26 @@ private > void addOperatingStatusDecorator(List operatingStatus = identifiable.getExtension(OperatingStatus.class); if (operatingStatus != null) { switch (operatingStatus.getStatus()) { - case PLANNED_OUTAGE -> nodeDecorators.add(getBranchStatusDecorator(node, direction, PLANNED_OUTAGE_BRANCH_NODE_DECORATOR)); - case FORCED_OUTAGE -> nodeDecorators.add(getBranchStatusDecorator(node, direction, FORCED_OUTAGE_BRANCH_NODE_DECORATOR)); + case PLANNED_OUTAGE -> nodeDecorators.add(getOperatingStatusDecorator(node, direction, PLANNED_OUTAGE_BRANCH_NODE_DECORATOR)); + case FORCED_OUTAGE -> nodeDecorators.add(getOperatingStatusDecorator(node, direction, FORCED_OUTAGE_BRANCH_NODE_DECORATOR)); case IN_OPERATION -> { /* No decorator for IN_OPERATION equipment */ } } } } } - private NodeDecorator getBranchStatusDecorator(Node node, Direction direction, String decoratorType) { - return (node instanceof Middle3WTNode middle3WTNode) ? - new NodeDecorator(decoratorType, getMiddle3WTDecoratorPosition(middle3WTNode, direction)) : - new NodeDecorator(decoratorType, getFeederDecoratorPosition(direction, decoratorType)); + private NodeDecorator getOperatingStatusDecorator(Node node, Direction direction, String decoratorType) { + if (node instanceof Middle3WTNode middle3WTNode) { + return new NodeDecorator(decoratorType, getMiddle3WTDecoratorPosition(middle3WTNode, direction)); + } else if (node instanceof BusNode) { + return new NodeDecorator(decoratorType, getBusDecoratorPosition()); + } else if (node instanceof FeederNode) { + return new NodeDecorator(decoratorType, getFeederDecoratorPosition(direction, decoratorType)); + } else if (node instanceof Internal2WTNode) { + return new NodeDecorator(decoratorType, getInternal2WTDecoratorPosition(node.getOrientation())); + } else { + return new NodeDecorator(decoratorType, getGenericDecoratorPosition()); + } } private List buildFeederInfos(ThreeWindingsTransformer transformer, ThreeSides side, boolean insideVoltageLevel) { diff --git a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestNodeDecoratorsNodeBreaker.java b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestNodeDecoratorsNodeBreaker.java index 45fdfe5e7..9cf47e1c1 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestNodeDecoratorsNodeBreaker.java +++ b/single-line-diagram/single-line-diagram-core/src/test/java/com/powsybl/sld/iidm/TestNodeDecoratorsNodeBreaker.java @@ -8,7 +8,10 @@ package com.powsybl.sld.iidm; import com.powsybl.diagram.test.Networks; +import com.powsybl.iidm.network.Network; import com.powsybl.sld.builders.NetworkGraphBuilder; +import com.powsybl.sld.layout.HorizontalSubstationLayoutFactory; +import com.powsybl.sld.layout.SmartVoltageLevelLayoutFactory; import com.powsybl.sld.library.ComponentSize; import com.powsybl.sld.model.coordinate.Direction; import com.powsybl.sld.model.graphs.SubstationGraph; @@ -18,6 +21,9 @@ import com.powsybl.sld.svg.DefaultLabelProvider; import com.powsybl.sld.svg.LabelPosition; import com.powsybl.sld.svg.LabelProvider; +import com.powsybl.sld.svg.styles.StyleProvidersList; +import com.powsybl.sld.svg.styles.iidm.HighlightLineStateStyleProvider; +import com.powsybl.sld.svg.styles.iidm.TopologicalStyleProvider; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -52,6 +58,18 @@ void testBranchStatusDecorators() { toSVG(g, "/NodeDecoratorsBranchStatusNodeBreaker.svg", componentLibrary, layoutParameters, svgParameters, getDefaultDiagramLabelProvider(), getDefaultDiagramStyleProvider())); } + @Test + void testBranchStatusForVerticalInternalPst() { + Network networkInternalPst = Networks.createNetworkWithInternalPstAndBranchStatus(); + SubstationGraph g = new NetworkGraphBuilder(networkInternalPst).buildSubstationGraph("s"); + + // Run horizontal substation layout + new HorizontalSubstationLayoutFactory().create(g, new SmartVoltageLevelLayoutFactory(networkInternalPst)).run(layoutParameters); + + assertEquals(toString("/VerticalInternalPstBranchStatusNodeBreaker.svg"), + toSVG(g, "/VerticalInternalPstBranchStatusNodeBreaker.svg", componentLibrary, layoutParameters, svgParameters, new DefaultLabelProvider(networkInternalPst, componentLibrary, layoutParameters, svgParameters), new StyleProvidersList(new TopologicalStyleProvider(networkInternalPst), new HighlightLineStateStyleProvider(networkInternalPst)))); + } + @Test void testSwitchDecorators() { diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/NodeDecoratorsBranchStatusBusBreaker.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/NodeDecoratorsBranchStatusBusBreaker.svg index 384b86219..0cb407c1a 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/resources/NodeDecoratorsBranchStatusBusBreaker.svg +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/NodeDecoratorsBranchStatusBusBreaker.svg @@ -215,7 +215,7 @@ - + diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/NodeDecoratorsBranchStatusNodeBreaker.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/NodeDecoratorsBranchStatusNodeBreaker.svg index c2b3def35..1c59a4d74 100644 --- a/single-line-diagram/single-line-diagram-core/src/test/resources/NodeDecoratorsBranchStatusNodeBreaker.svg +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/NodeDecoratorsBranchStatusNodeBreaker.svg @@ -230,7 +230,7 @@ - + @@ -606,6 +606,9 @@ BBS2 + + + diff --git a/single-line-diagram/single-line-diagram-core/src/test/resources/VerticalInternalPstBranchStatusNodeBreaker.svg b/single-line-diagram/single-line-diagram-core/src/test/resources/VerticalInternalPstBranchStatusNodeBreaker.svg new file mode 100644 index 000000000..13e9be67c --- /dev/null +++ b/single-line-diagram/single-line-diagram-core/src/test/resources/VerticalInternalPstBranchStatusNodeBreaker.svg @@ -0,0 +1,264 @@ + + + + + + + vl1 + + + + bbs1 + + + + bbs2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + l + + + +