From 09d0a822e6b7859e5952001fb347dc119be02faf Mon Sep 17 00:00:00 2001 From: Romain Courtier Date: Fri, 29 Nov 2024 16:42:47 +0100 Subject: [PATCH 1/2] Use PowerTransformerEnd.endNumber instead of Terminal.sequenceNumber to sort transformer windings Signed-off-by: Romain Courtier --- .../AbstractTransformerConversion.java | 5 +- .../cgmes/model/AbstractCgmesModel.java | 7 +- .../com/powsybl/cgmes/model/WindingType.java | 32 +++++--- .../powsybl/cgmes/model/WindingTypeTest.java | 75 +++++++++++++++++++ 4 files changed, 102 insertions(+), 17 deletions(-) create mode 100644 cgmes/cgmes-model/src/test/java/com/powsybl/cgmes/model/WindingTypeTest.java diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/elements/transformers/AbstractTransformerConversion.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/elements/transformers/AbstractTransformerConversion.java index a13b5cd1f6a..2f6a272dba5 100644 --- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/elements/transformers/AbstractTransformerConversion.java +++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/elements/transformers/AbstractTransformerConversion.java @@ -16,6 +16,7 @@ import com.powsybl.cgmes.extensions.CgmesTapChangers; import com.powsybl.cgmes.extensions.CgmesTapChangersAdder; import com.powsybl.cgmes.model.CgmesNames; +import com.powsybl.cgmes.model.WindingType; import com.powsybl.iidm.network.*; import com.powsybl.triplestore.api.PropertyBag; import com.powsybl.triplestore.api.PropertyBags; @@ -111,10 +112,8 @@ protected CgmesRegulatingControlPhase setContextRegulatingDataPhase(TapChanger t @Override protected void addAliasesAndProperties(Identifiable identifiable) { super.addAliasesAndProperties(identifiable); - int end = 1; for (PropertyBag p : ps) { - identifiable.addAlias(p.getId("TransformerEnd"), Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + CgmesNames.TRANSFORMER_END + end); - end++; + identifiable.addAlias(p.getId("TransformerEnd"), Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + CgmesNames.TRANSFORMER_END + WindingType.endNumber(p)); } List ptcs = context.cgmes().phaseTapChangerListForPowerTransformer(identifiable.getId()); if (ptcs != null) { diff --git a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/AbstractCgmesModel.java b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/AbstractCgmesModel.java index 6006049b616..59b4095c8e3 100644 --- a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/AbstractCgmesModel.java +++ b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/AbstractCgmesModel.java @@ -19,7 +19,6 @@ import java.io.IOException; import java.io.InputStream; import java.util.*; -import java.util.stream.Collectors; /** * @author Luma ZamarreƱo {@literal } @@ -206,10 +205,8 @@ private Map computeGroupedTransformerEnds() { .forEach(tends -> { PropertyBags tends1 = new PropertyBags( tends.getValue().stream() - .sorted(Comparator - .comparing(WindingType::fromTransformerEnd) - .thenComparing(end -> end.asInt(endNumber, -1))) - .collect(Collectors.toList())); + .sorted(Comparator.comparing(WindingType::endNumber)) + .toList()); tends.setValue(tends1); }); return gends; diff --git a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/WindingType.java b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/WindingType.java index 049302e5969..918ee5ef6ae 100644 --- a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/WindingType.java +++ b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/WindingType.java @@ -17,13 +17,14 @@ public enum WindingType { PRIMARY, SECONDARY, TERTIARY; - public static WindingType fromTransformerEnd(PropertyBag end) { - // For CIM14 (CIM ENTSOE Profile1) primary is determined by windingType - // For CIM16 (CGMES) primary is defined by the corresponding terminal sequence number: - // "The Terminal.sequenceNumber distinguishes the terminals much as previously done by - // TransformerWinding.windingType:WindingType" - + /** + * Retrieve the WindingType for the given transformer winding/end. + * @param end A PropertyBag with the transformer winding/end properties. + * @return The WindingType (PRIMARY/SECONDARY/TERTIARY) corresponding to the given transformer winding/end. + */ + public static WindingType windingType(PropertyBag end) { if (end.containsKey("windingType")) { + // For CIM14 (CIM ENTSOE Profile1) primary is determined by TransformerWinding.windingType String wtype = end.getLocal("windingType"); if (wtype.endsWith("WindingType.primary")) { return WindingType.PRIMARY; @@ -32,10 +33,23 @@ public static WindingType fromTransformerEnd(PropertyBag end) { } else if (wtype.endsWith("WindingType.tertiary")) { return WindingType.TERTIARY; } - } else if (end.containsKey("terminalSequenceNumber")) { - // Terminal.sequenceNumber := 1, 2 ,3 ... - return WindingType.values()[end.asInt("terminalSequenceNumber") - 1]; + } else if (end.containsKey("endNumber")) { + // For CIM16 (CGMES 2.4.15) primary is defined by TransformerEnd.endNumber + try { + return WindingType.values()[end.asInt("endNumber") - 1]; + } catch (Exception e) { + return WindingType.PRIMARY; + } } return WindingType.PRIMARY; } + + /** + * Retrieve the endNumber for the given transformer winding/end. + * @param end A PropertyBag with the transformer winding/end properties. + * @return The endNumber value (1/2/3) corresponding to the given transformer winding/end. + */ + public static int endNumber(PropertyBag end) { + return windingType(end).ordinal() + 1; + } } diff --git a/cgmes/cgmes-model/src/test/java/com/powsybl/cgmes/model/WindingTypeTest.java b/cgmes/cgmes-model/src/test/java/com/powsybl/cgmes/model/WindingTypeTest.java new file mode 100644 index 00000000000..e613ad651a5 --- /dev/null +++ b/cgmes/cgmes-model/src/test/java/com/powsybl/cgmes/model/WindingTypeTest.java @@ -0,0 +1,75 @@ +/** + * Copyright (c) 2024, 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.model; + +import com.powsybl.triplestore.api.PropertyBag; +import org.junit.jupiter.api.Test; + +import java.util.Collections; + +import static org.junit.jupiter.api.Assertions.*; + +/** + * @author Romain Courtier {@literal } + */ +class WindingTypeTest { + + PropertyBag end1; + PropertyBag end2; + PropertyBag end3; + PropertyBag end4; + + static final String WINDING_TYPE = "windingType"; + static final String END_NUMBER = "endNumber"; + + @Test + void cim14WindingTypeTest() { + end1 = new PropertyBag(Collections.singletonList(WINDING_TYPE), true); + end1.put(WINDING_TYPE, "http://iec.ch/TC57/2009/CIM-schema-cim14#WindingType.primary"); + assertEquals(WindingType.PRIMARY, WindingType.windingType(end1)); + assertEquals(1, WindingType.endNumber(end1)); + + end2 = new PropertyBag(Collections.singletonList(WINDING_TYPE), true); + end2.put(WINDING_TYPE, "http://iec.ch/TC57/2009/CIM-schema-cim14#WindingType.secondary"); + assertEquals(WindingType.SECONDARY, WindingType.windingType(end2)); + assertEquals(2, WindingType.endNumber(end2)); + + end3 = new PropertyBag(Collections.singletonList(WINDING_TYPE), true); + end3.put(WINDING_TYPE, "http://iec.ch/TC57/2009/CIM-schema-cim14#WindingType.tertiary"); + assertEquals(WindingType.TERTIARY, WindingType.windingType(end3)); + assertEquals(3, WindingType.endNumber(end3)); + + end4 = new PropertyBag(Collections.singletonList(WINDING_TYPE), true); + end4.put(WINDING_TYPE, "WindingType.quaternary"); + assertEquals(WindingType.PRIMARY, WindingType.windingType(end4)); + assertEquals(1, WindingType.endNumber(end4)); + } + + @Test + void cim16WindingTypeTest() { + end1 = new PropertyBag(Collections.singletonList(END_NUMBER), true); + end1.put(END_NUMBER, "1"); + assertEquals(WindingType.PRIMARY, WindingType.windingType(end1)); + assertEquals(1, WindingType.endNumber(end1)); + + end2 = new PropertyBag(Collections.singletonList(END_NUMBER), true); + end2.put(END_NUMBER, "2"); + assertEquals(WindingType.SECONDARY, WindingType.windingType(end2)); + assertEquals(2, WindingType.endNumber(end2)); + + end3 = new PropertyBag(Collections.singletonList(END_NUMBER), true); + end3.put(END_NUMBER, "3"); + assertEquals(WindingType.TERTIARY, WindingType.windingType(end3)); + assertEquals(3, WindingType.endNumber(end3)); + + end4 = new PropertyBag(Collections.singletonList(END_NUMBER), true); + end4.put(END_NUMBER, "4"); + assertEquals(WindingType.PRIMARY, WindingType.windingType(end4)); + assertEquals(1, WindingType.endNumber(end4)); + } +} From f680d6a87ee5358486897484bbfe7624e00e4fe9 Mon Sep 17 00:00:00 2001 From: Romain Courtier Date: Tue, 3 Dec 2024 15:03:57 +0100 Subject: [PATCH 2/2] Add an UNKNOWN value to the WindingType enum Signed-off-by: Romain Courtier --- .../com/powsybl/cgmes/model/WindingType.java | 20 +++++++++---------- .../powsybl/cgmes/model/WindingTypeTest.java | 8 ++++---- 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/WindingType.java b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/WindingType.java index 918ee5ef6ae..244507730db 100644 --- a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/WindingType.java +++ b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/WindingType.java @@ -15,7 +15,7 @@ */ public enum WindingType { - PRIMARY, SECONDARY, TERTIARY; + PRIMARY, SECONDARY, TERTIARY, UNKNOWN; /** * Retrieve the WindingType for the given transformer winding/end. @@ -25,23 +25,21 @@ public enum WindingType { public static WindingType windingType(PropertyBag end) { if (end.containsKey("windingType")) { // For CIM14 (CIM ENTSOE Profile1) primary is determined by TransformerWinding.windingType - String wtype = end.getLocal("windingType"); - if (wtype.endsWith("WindingType.primary")) { - return WindingType.PRIMARY; - } else if (wtype.endsWith("WindingType.secondary")) { - return WindingType.SECONDARY; - } else if (wtype.endsWith("WindingType.tertiary")) { - return WindingType.TERTIARY; - } + return switch (end.getLocal("windingType")) { + case "WindingType.primary" -> WindingType.PRIMARY; + case "WindingType.secondary" -> WindingType.SECONDARY; + case "WindingType.tertiary" -> WindingType.TERTIARY; + default -> WindingType.UNKNOWN; + }; } else if (end.containsKey("endNumber")) { // For CIM16 (CGMES 2.4.15) primary is defined by TransformerEnd.endNumber try { return WindingType.values()[end.asInt("endNumber") - 1]; } catch (Exception e) { - return WindingType.PRIMARY; + return WindingType.UNKNOWN; } } - return WindingType.PRIMARY; + return WindingType.UNKNOWN; } /** diff --git a/cgmes/cgmes-model/src/test/java/com/powsybl/cgmes/model/WindingTypeTest.java b/cgmes/cgmes-model/src/test/java/com/powsybl/cgmes/model/WindingTypeTest.java index e613ad651a5..c1c23839e55 100644 --- a/cgmes/cgmes-model/src/test/java/com/powsybl/cgmes/model/WindingTypeTest.java +++ b/cgmes/cgmes-model/src/test/java/com/powsybl/cgmes/model/WindingTypeTest.java @@ -46,8 +46,8 @@ void cim14WindingTypeTest() { end4 = new PropertyBag(Collections.singletonList(WINDING_TYPE), true); end4.put(WINDING_TYPE, "WindingType.quaternary"); - assertEquals(WindingType.PRIMARY, WindingType.windingType(end4)); - assertEquals(1, WindingType.endNumber(end4)); + assertEquals(WindingType.UNKNOWN, WindingType.windingType(end4)); + assertEquals(4, WindingType.endNumber(end4)); } @Test @@ -69,7 +69,7 @@ void cim16WindingTypeTest() { end4 = new PropertyBag(Collections.singletonList(END_NUMBER), true); end4.put(END_NUMBER, "4"); - assertEquals(WindingType.PRIMARY, WindingType.windingType(end4)); - assertEquals(1, WindingType.endNumber(end4)); + assertEquals(WindingType.UNKNOWN, WindingType.windingType(end4)); + assertEquals(4, WindingType.endNumber(end4)); } }