Repository: powsybl/powsybl-core
Pull request #3307: Refactor `CgmesNamespace` interface
Author: login: rcourtier
Labels: name: CGMES
name: Breaking Change
description: API is broken
name: Release 03/2025
Created: 2025-02-04T10:46:11Z | Merged: 2025-03-05T13:26:25Z

**Please check if the PR fulfills these requirements**
<!-- please use `'[x]'` to check the checkboxes, or submit the PR and then click the checkboxes -->
- [X] The commit message follows our guidelines
- [X] Tests for the changes have been added (for bug fixes / features)
- [ ] Docs have been added / updated (for bug fixes / features)


**Does this PR already have an issue describing the problem?**
<!-- If so, link to this issue using `'Fixes #XXX'` and skip the rest -->
No.


**What kind of change does this PR introduce?**
<!-- Bug fix, feature, docs update, ... -->
Refactoring.


**Does this PR introduce a new Powsybl Action implying to be implemented in simulators or pypowsybl?**
- [ ] Yes, the corresponding issue is [here](link)
- [X] No

**What is the current behavior?**
<!-- You can also link to an open issue here -->
Some methods had been created in the `CgmesNamespace` interface to make the distinction between the CIM14/CIM16/CIM100 schemas. This is not the right place to make that and it's not necessary since it is as simple to request the cim version number to distinguish what needs to be exported.


**What is the new behavior (if this is a feature change)?**
<!-- -->
Cim version number is used in export classes to make the distinction between cim schemas.


**Does this PR introduce a breaking change or deprecate an API?**
- [X] Yes
- [ ] No

**If yes, please check if the following requirements are fulfilled**
<!-- If no breaking changes or API deprecations were introduced, delete this section -->
- [X] The *Breaking Change* or *Deprecated* label has been added
- [X] The migration steps are described in the following section

**What changes might users need to make in their application due to this PR? (migration steps)**
<!-- If this PR introduces a breaking change, describe the migration steps -->
<!-- The content of this section will be copied in the migration guide -->

If you are calling one of the following methods of `CgmesNamespace.Cim`, you must replace it by:
| Previously | Now |
| --- | --- |
| `getLimitTypeAttributeName()` | `getLimitTypeAttributeName()` <br/> in `OperationalLimitTypeEq` class <br/> of `com.powsybl.cgmes.conversion.export.elements` package |
| `getLimitKindClassName()` | `getLimitKindClassName()` <br/> in `OperationalLimitTypeEq` class <br/> of `com.powsybl.cgmes.conversion.export.elements` package |
| `getLimitValueAttributeName()` | `getLimitValueAttributeName()` <br/> in `LoadingLimitEq` class <br/> of `com.powsybl.cgmes.conversion.export.elements` package |
| `writeConnectivityNodes()` | `getVersion() == 100` |
| `writeGeneratingUnitInitialP()` | `getVersion() == 16` |
| `writeLimitInfiniteDuration()` | `getVersion() == 100` |
| `writeTculControlMode()` | `getVersion() <= 16` |





**Other information**:
<!-- if any of the questions/checkboxes don't apply, please delete them entirely -->



Diff:
diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/CgmesExportContext.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/CgmesExportContext.java
index f62affac4c9..485e529eeea 100644
--- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/CgmesExportContext.java
+++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/CgmesExportContext.java
@@ -674,11 +674,7 @@ public BaseVoltageMapping.BaseVoltageSource getBaseVoltageByNominalVoltage(doubl
     }
 
     public boolean writeConnectivityNodes() {
-        boolean writeConnectivityNodes = cim.writeConnectivityNodes();
-        if (!writeConnectivityNodes) {
-            return topologyKind == CgmesTopologyKind.NODE_BREAKER;
-        }
-        return true;
+        return getCimVersion() == 100 || topologyKind == CgmesTopologyKind.NODE_BREAKER;
     }
 
     public Collection<String> getRegionsIds() {
diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/EquipmentExport.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/EquipmentExport.java
index 87eab545f65..85a93388784 100644
--- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/EquipmentExport.java
+++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/EquipmentExport.java
@@ -63,15 +63,8 @@ public static void write(Network network, XMLStreamWriter writer, CgmesExportCon
 
     public static void write(Network network, XMLStreamWriter writer, CgmesExportContext context, CgmesMetadataModel model) {
         try {
-            boolean writeConnectivityNodes = context.writeConnectivityNodes();
-
             String cimNamespace = context.getCim().getNamespace();
             String euNamespace = context.getCim().getEuNamespace();
-            String limitValueAttributeName = context.getCim().getLimitValueAttributeName();
-            String limitTypeAttributeName = context.getCim().getLimitTypeAttributeName();
-            String limitKindClassName = context.getCim().getLimitKindClassName();
-            boolean writeInfiniteDuration = context.getCim().writeLimitInfiniteDuration();
-            boolean writeInitialP = context.getCim().writeGeneratingUnitInitialP();
             CgmesExportUtil.writeRdfRoot(cimNamespace, context.getCim().getEuPrefix(), euNamespace, writer);
 
             if (context.getCimVersion() >= 16) {
@@ -85,7 +78,7 @@ public static void write(Network network, XMLStreamWriter writer, CgmesExportCon
             Set<String> exportedLimitTypes = new HashSet<>();
             LoadGroups loadGroups = new LoadGroups();
 
-            if (writeConnectivityNodes) {
+            if (context.writeConnectivityNodes()) {
                 writeConnectivityNodes(network, mapNodeKey2NodeId, cimNamespace, writer, context);
             }
             writeTerminals(network, mapTerminal2Id, mapNodeKey2NodeId, cimNamespace, writer, context);
@@ -96,15 +89,15 @@ public static void write(Network network, XMLStreamWriter writer, CgmesExportCon
             writeBusbarSections(network, cimNamespace, writer, context);
             writeLoads(network, loadGroups, cimNamespace, writer, context);
             String loadAreaId = writeLoadGroups(network, loadGroups.found(), cimNamespace, writer, context);
-            writeGenerators(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, writeInitialP, writer, context);
-            writeBatteries(network, cimNamespace, writeInitialP, writer, context);
+            writeGenerators(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, writer, context);
+            writeBatteries(network, cimNamespace, writer, context);
             writeShuntCompensators(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, writer, context);
             writeStaticVarCompensators(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, writer, context);
-            writeLines(network, mapTerminal2Id, cimNamespace, euNamespace, limitValueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
-            writeTwoWindingsTransformers(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, euNamespace, limitValueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
-            writeThreeWindingsTransformers(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, euNamespace, limitValueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeLines(network, mapTerminal2Id, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
+            writeTwoWindingsTransformers(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
+            writeThreeWindingsTransformers(network, mapTerminal2Id, regulatingControlsWritten, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
 
-            writeDanglingLines(network, mapTerminal2Id, cimNamespace, euNamespace, limitValueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context, exportedBaseVoltagesByNominalV);
+            writeDanglingLines(network, mapTerminal2Id, cimNamespace, euNamespace, exportedLimitTypes, writer, context, exportedBaseVoltagesByNominalV);
             writeHvdcLines(network, mapTerminal2Id, mapNodeKey2NodeId, cimNamespace, writer, context);
 
             writeControlAreas(loadAreaId, network, cimNamespace, euNamespace, writer, context);
@@ -376,7 +369,7 @@ public static void writeEnergySource(String id, String name, String equipmentCon
         writer.writeEndElement();
     }
 
-    private static void writeGenerators(Network network, Map<Terminal, String> mapTerminal2Id, Set<String> regulatingControlsWritten, String cimNamespace, boolean writeInitialP,
+    private static void writeGenerators(Network network, Map<Terminal, String> mapTerminal2Id, Set<String> regulatingControlsWritten, String cimNamespace,
                                         XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         // Multiple synchronous machines may be grouped in the same generating unit
         // We have to write each generating unit only once
@@ -412,7 +405,7 @@ private static void writeGenerators(Network network, Map<Terminal, String> mapTe
                     break;
                 case CgmesNames.SYNCHRONOUS_MACHINE:
                     regulatingControlId = RegulatingControlEq.writeRegulatingControlEq(generator, exportedTerminalId(mapTerminal2Id, regulatingTerminal), regulatingControlsWritten, mode, cimNamespace, writer, context);
-                    writeSynchronousMachine(generator, cimNamespace, writeInitialP,
+                    writeSynchronousMachine(generator, cimNamespace,
                             generator.getMinP(), generator.getMaxP(), generator.getTargetP(), generator.getRatedS(), generator.getEnergySource(),
                             regulatingControlId, writer, context, generatingUnitsWritten);
                     break;
@@ -427,19 +420,19 @@ private static double obtainGeneratorGovernorScd(Generator generator) {
         return governorScd == null ? 0.0 : Double.parseDouble(governorScd);
     }
 
-    private static void writeBatteries(Network network, String cimNamespace, boolean writeInitialP,
+    private static void writeBatteries(Network network, String cimNamespace,
                                         XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         // Multiple synchronous machines may be grouped in the same generating unit
         // We have to write each generating unit only once
         Set<String> generatingUnitsWritten = new HashSet<>();
         for (Battery battery : network.getBatteries()) {
-            writeSynchronousMachine(battery, cimNamespace, writeInitialP,
+            writeSynchronousMachine(battery, cimNamespace,
                     battery.getMinP(), battery.getMaxP(), battery.getTargetP(), Double.NaN, EnergySource.HYDRO, null,
                     writer, context, generatingUnitsWritten);
         }
     }
 
-    private static <I extends ReactiveLimitsHolder & Injection<I>> void writeSynchronousMachine(I i, String cimNamespace, boolean writeInitialP,
+    private static <I extends ReactiveLimitsHolder & Injection<I>> void writeSynchronousMachine(I i, String cimNamespace,
                                                                                                 double minP, double maxP, double targetP, double ratedS, EnergySource energySource, String regulatingControlId,
                                                                                                 XMLStreamWriter writer, CgmesExportContext context, Set<String> generatingUnitsWritten) throws XMLStreamException {
 
@@ -464,7 +457,7 @@ private static <I extends ReactiveLimitsHolder & Injection<I>> void writeSynchro
             // We have not preserved the names of generating units
             // We name generating units based on the first machine found
             String generatingUnitName = "GU_" + i.getNameOrId();
-            GeneratingUnitEq.write(generatingUnit, generatingUnitName, energySource, minP, maxP, targetP, cimNamespace, writeInitialP,
+            GeneratingUnitEq.write(generatingUnit, generatingUnitName, energySource, minP, maxP, targetP, cimNamespace,
                     i.getTerminal().getVoltageLevel().getSubstation().map(s -> context.getNamingStrategy().getCgmesId(s)).orElse(null),
                     hydroPowerPlantId, windGenUnitType, writer, context);
             generatingUnitsWritten.add(generatingUnit);
@@ -622,19 +615,19 @@ private static void writeStaticVarCompensators(Network network, Map<Terminal, St
         }
     }
 
-    private static void writeLines(Network network, Map<Terminal, String> mapTerminal2Id, String cimNamespace, String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+    private static void writeLines(Network network, Map<Terminal, String> mapTerminal2Id, String cimNamespace, String euNamespace, Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         for (Line line : network.getLines()) {
             String baseVoltage = null;
             if (line.getTerminal1().getVoltageLevel().getNominalV() == line.getTerminal2().getVoltageLevel().getNominalV()) {
                 baseVoltage = context.getBaseVoltageByNominalVoltage(line.getTerminal1().getVoltageLevel().getNominalV()).getId();
             }
             AcLineSegmentEq.write(context.getNamingStrategy().getCgmesId(line), line.getNameOrId(), baseVoltage, line.getR(), line.getX(), line.getG1() + line.getG2(), line.getB1() + line.getB2(), cimNamespace, writer, context);
-            writeBranchLimits(line, exportedTerminalId(mapTerminal2Id, line.getTerminal1()), exportedTerminalId(mapTerminal2Id, line.getTerminal2()), cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeBranchLimits(line, exportedTerminalId(mapTerminal2Id, line.getTerminal1()), exportedTerminalId(mapTerminal2Id, line.getTerminal2()), cimNamespace, euNamespace, exportedLimitTypes, writer, context);
         }
     }
 
     private static void writeTwoWindingsTransformers(Network network, Map<Terminal, String> mapTerminal2Id, Set<String> regulatingControlsWritten, String cimNamespace,
-                                                    String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+                                                    String euNamespace, Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         for (TwoWindingsTransformer twt : network.getTwoWindingsTransformers()) {
             CgmesExportUtil.addUpdateCgmesTapChangerExtension(twt, context);
 
@@ -668,7 +661,7 @@ private static void writeTwoWindingsTransformers(Network network, Map<Terminal,
             adjustTapChangerAliases2wt(twt, twt.getRatioTapChanger(), CgmesNames.RATIO_TAP_CHANGER);
             writePhaseTapChanger(twt, twt.getPhaseTapChanger(), twt.getNameOrId(), endNumber, end1Id, twt.getRatedU1(), regulatingControlsWritten, cimNamespace, writer, context);
             writeRatioTapChanger(twt, twt.getRatioTapChanger(), twt.getNameOrId(), endNumber, end1Id, twt.getRatedU1(), regulatingControlsWritten, cimNamespace, writer, context);
-            writeBranchLimits(twt, exportedTerminalId(mapTerminal2Id, twt.getTerminal1()), exportedTerminalId(mapTerminal2Id, twt.getTerminal2()), cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeBranchLimits(twt, exportedTerminalId(mapTerminal2Id, twt.getTerminal1()), exportedTerminalId(mapTerminal2Id, twt.getTerminal2()), cimNamespace, euNamespace, exportedLimitTypes, writer, context);
         }
     }
 
@@ -692,7 +685,7 @@ private static void adjustTapChangerAliases2wt(TwoWindingsTransformer transforme
     }
 
     private static void writeThreeWindingsTransformers(Network network, Map<Terminal, String> mapTerminal2Id, Set<String> regulatingControlsWritten, String cimNamespace,
-                                                      String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+                                                      String euNamespace, Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         for (ThreeWindingsTransformer twt : network.getThreeWindingsTransformers()) {
             CgmesExportUtil.addUpdateCgmesTapChangerExtension(twt, context);
 
@@ -702,11 +695,11 @@ private static void writeThreeWindingsTransformers(Network network, Map<Terminal
             EndNumberAssignerForThreeWindingsTransformer endNumberAssigner = new EndNumberAssignerForThreeWindingsTransformer(twt, context.exportTransformersWithHighestVoltageAtEnd1());
 
             String end1Id = context.getNamingStrategy().getCgmesIdFromAlias(twt, Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + CgmesNames.TRANSFORMER_END + 1);
-            writeThreeWindingsTransformerEnd(twt, context.getNamingStrategy().getCgmesId(twt), twt.getNameOrId() + "_1", end1Id, endNumberAssigner.getEndNumberForLeg1(), 1, twt.getLeg1(), ratedU0, exportedTerminalId(mapTerminal2Id, twt.getLeg1().getTerminal()), regulatingControlsWritten, cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeThreeWindingsTransformerEnd(twt, context.getNamingStrategy().getCgmesId(twt), twt.getNameOrId() + "_1", end1Id, endNumberAssigner.getEndNumberForLeg1(), 1, twt.getLeg1(), ratedU0, exportedTerminalId(mapTerminal2Id, twt.getLeg1().getTerminal()), regulatingControlsWritten, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
             String end2Id = context.getNamingStrategy().getCgmesIdFromAlias(twt, Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + CgmesNames.TRANSFORMER_END + 2);
-            writeThreeWindingsTransformerEnd(twt, context.getNamingStrategy().getCgmesId(twt), twt.getNameOrId() + "_2", end2Id, endNumberAssigner.getEndNumberForLeg2(), 2, twt.getLeg2(), ratedU0, exportedTerminalId(mapTerminal2Id, twt.getLeg2().getTerminal()), regulatingControlsWritten, cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeThreeWindingsTransformerEnd(twt, context.getNamingStrategy().getCgmesId(twt), twt.getNameOrId() + "_2", end2Id, endNumberAssigner.getEndNumberForLeg2(), 2, twt.getLeg2(), ratedU0, exportedTerminalId(mapTerminal2Id, twt.getLeg2().getTerminal()), regulatingControlsWritten, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
             String end3Id = context.getNamingStrategy().getCgmesIdFromAlias(twt, Conversion.CGMES_PREFIX_ALIAS_PROPERTIES + CgmesNames.TRANSFORMER_END + 3);
-            writeThreeWindingsTransformerEnd(twt, context.getNamingStrategy().getCgmesId(twt), twt.getNameOrId() + "_3", end3Id, endNumberAssigner.getEndNumberForLeg3(), 3, twt.getLeg3(), ratedU0, exportedTerminalId(mapTerminal2Id, twt.getLeg3().getTerminal()), regulatingControlsWritten, cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeThreeWindingsTransformerEnd(twt, context.getNamingStrategy().getCgmesId(twt), twt.getNameOrId() + "_3", end3Id, endNumberAssigner.getEndNumberForLeg3(), 3, twt.getLeg3(), ratedU0, exportedTerminalId(mapTerminal2Id, twt.getLeg3().getTerminal()), regulatingControlsWritten, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
         }
     }
 
@@ -827,7 +820,7 @@ private double getEnd2B() {
         private final double a02;
     }
 
-    private static void writeThreeWindingsTransformerEnd(ThreeWindingsTransformer twt, String twtId, String twtName, String endId, int endNumber, int legNumber, ThreeWindingsTransformer.Leg leg, double ratedU0, String terminalId, Set<String> regulatingControlsWritten, String cimNamespace, String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+    private static void writeThreeWindingsTransformerEnd(ThreeWindingsTransformer twt, String twtId, String twtName, String endId, int endNumber, int legNumber, ThreeWindingsTransformer.Leg leg, double ratedU0, String terminalId, Set<String> regulatingControlsWritten, String cimNamespace, String euNamespace, Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         // structural ratio at end1
         double a0 = leg.getRatedU() / ratedU0;
         // move structural ratio from end1 to end2
@@ -840,7 +833,7 @@ private static void writeThreeWindingsTransformerEnd(ThreeWindingsTransformer tw
         PowerTransformerEq.writeEnd(endId, twtName, twtId, endNumber, r, x, g, b, leg.getRatedS(), leg.getRatedU(), terminalId, baseVoltage.getId(), cimNamespace, writer, context);
         writePhaseTapChanger(twt, leg.getPhaseTapChanger(), twtName, legNumber, endId, leg.getRatedU(), regulatingControlsWritten, cimNamespace, writer, context);
         writeRatioTapChanger(twt, leg.getRatioTapChanger(), twtName, legNumber, endId, leg.getRatedU(), regulatingControlsWritten, cimNamespace, writer, context);
-        writeFlowsLimits(twt, leg, terminalId, cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+        writeFlowsLimits(twt, leg, terminalId, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
     }
 
     private static <C extends Connectable<C>> void writePhaseTapChanger(C eq, PhaseTapChanger ptc, String twtName, int endNumber, String endId, double neutralU, Set<String> regulatingControlsWritten, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
@@ -961,13 +954,13 @@ private static int getRatioTapChangerNeutralStep(RatioTapChanger rtc) {
         return neutralStep;
     }
 
-    private static void writeDanglingLines(Network network, Map<Terminal, String> mapTerminal2Id, String cimNamespace, String euNamespace, String valueAttributeName, String limitTypeAttributeName,
-                                            String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context, Set<Double> exportedBaseVoltagesByNominalV) throws XMLStreamException {
+    private static void writeDanglingLines(Network network, Map<Terminal, String> mapTerminal2Id, String cimNamespace, String euNamespace,
+                                           Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context, Set<Double> exportedBaseVoltagesByNominalV) throws XMLStreamException {
         List<String> exported = new ArrayList<>();
 
         for (DanglingLine danglingLine : network.getDanglingLines(DanglingLineFilter.UNPAIRED)) {
             writeUnpairedOrPairedDanglingLines(Collections.singletonList(danglingLine), mapTerminal2Id, cimNamespace, euNamespace,
-                    valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer,
+                    exportedLimitTypes, writer,
                     context, exportedBaseVoltagesByNominalV, exported);
         }
 
@@ -975,13 +968,13 @@ private static void writeDanglingLines(Network network, Map<Terminal, String> ma
         for (String pairingKey : pairingKeys) {
             List<DanglingLine> danglingLineList = network.getDanglingLineStream(DanglingLineFilter.PAIRED).filter(danglingLine -> pairingKey.equals(danglingLine.getPairingKey())).toList();
             writeUnpairedOrPairedDanglingLines(danglingLineList, mapTerminal2Id, cimNamespace, euNamespace,
-                    valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer,
+                    exportedLimitTypes, writer,
                     context, exportedBaseVoltagesByNominalV, exported);
         }
     }
 
     private static void writeUnpairedOrPairedDanglingLines(List<DanglingLine> danglingLineList, Map<Terminal, String> mapTerminal2Id, String cimNamespace, String euNamespace,
-                                                           String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer,
+                                                           Set<String> exportedLimitTypes, XMLStreamWriter writer,
                                                            CgmesExportContext context, Set<Double> exportedBaseVoltagesByNominalV, List<String> exported) throws XMLStreamException {
 
         String baseVoltageId = writeDanglingLinesBaseVoltage(danglingLineList, cimNamespace, writer, context, exportedBaseVoltagesByNominalV);
@@ -995,10 +988,10 @@ private static void writeUnpairedOrPairedDanglingLines(List<DanglingLine> dangli
             AcLineSegmentEq.write(context.getNamingStrategy().getCgmesId(danglingLine), danglingLine.getNameOrId(),
                     context.getBaseVoltageByNominalVoltage(danglingLine.getTerminal().getVoltageLevel().getNominalV()).getId(),
                     danglingLine.getR(), danglingLine.getX(), danglingLine.getG(), danglingLine.getB(), cimNamespace, writer, context);
-            writeFlowsLimits(danglingLine, danglingLine, exportedTerminalId(mapTerminal2Id, danglingLine.getTerminal()), cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeFlowsLimits(danglingLine, danglingLine, exportedTerminalId(mapTerminal2Id, danglingLine.getTerminal()), cimNamespace, euNamespace, exportedLimitTypes, writer, context);
             danglingLine.getAliasFromType("CGMES." + TERMINAL_BOUNDARY).ifPresent(terminalBdId -> {
                 try {
-                    writeFlowsLimits(danglingLine, danglingLine, terminalBdId, cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+                    writeFlowsLimits(danglingLine, danglingLine, terminalBdId, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
                 } catch (XMLStreamException e) {
                     throw new UncheckedXmlStreamException(e);
                 }
@@ -1176,7 +1169,7 @@ private static String writeFictitiousVoltageLevelFor(Identifiable<?> identifiabl
         return voltageLevelId;
     }
 
-    private static void writeBranchLimits(Branch<?> branch, String terminalId1, String terminalId2, String cimNamespace, String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+    private static void writeBranchLimits(Branch<?> branch, String terminalId1, String terminalId2, String cimNamespace, String euNamespace, Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         Collection<OperationalLimitsGroup> limitsGroups1 = new ArrayList<>();
         if (context.isExportAllLimitsGroup()) {
             limitsGroups1.addAll(branch.getOperationalLimitsGroups1());
@@ -1184,7 +1177,7 @@ private static void writeBranchLimits(Branch<?> branch, String terminalId1, Stri
             branch.getSelectedOperationalLimitsGroup1().ifPresent(limitsGroups1::add);
         }
         for (OperationalLimitsGroup limitsGroup : limitsGroups1) {
-            writeLimitsGroup(branch, limitsGroup, terminalId1, cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeLimitsGroup(branch, limitsGroup, terminalId1, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
         }
 
         Collection<OperationalLimitsGroup> limitsGroups2 = new ArrayList<>();
@@ -1194,11 +1187,11 @@ private static void writeBranchLimits(Branch<?> branch, String terminalId1, Stri
             branch.getSelectedOperationalLimitsGroup2().ifPresent(limitsGroups2::add);
         }
         for (OperationalLimitsGroup limitsGroup : limitsGroups2) {
-            writeLimitsGroup(branch, limitsGroup, terminalId2, cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeLimitsGroup(branch, limitsGroup, terminalId2, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
         }
     }
 
-    private static void writeFlowsLimits(Identifiable<?> identifiable, FlowsLimitsHolder holder, String terminalId, String cimNamespace, String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+    private static void writeFlowsLimits(Identifiable<?> identifiable, FlowsLimitsHolder holder, String terminalId, String cimNamespace, String euNamespace, Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         Collection<OperationalLimitsGroup> limitsGroups = new ArrayList<>();
         if (context.isExportAllLimitsGroup()) {
             limitsGroups.addAll(holder.getOperationalLimitsGroups());
@@ -1206,11 +1199,11 @@ private static void writeFlowsLimits(Identifiable<?> identifiable, FlowsLimitsHo
             holder.getSelectedOperationalLimitsGroup().ifPresent(limitsGroups::add);
         }
         for (OperationalLimitsGroup limitsGroup : limitsGroups) {
-            writeLimitsGroup(identifiable, limitsGroup, terminalId, cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeLimitsGroup(identifiable, limitsGroup, terminalId, cimNamespace, euNamespace, exportedLimitTypes, writer, context);
         }
     }
 
-    private static void writeLimitsGroup(Identifiable<?> identifiable, OperationalLimitsGroup limitsGroup, String terminalId, String cimNamespace, String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+    private static void writeLimitsGroup(Identifiable<?> identifiable, OperationalLimitsGroup limitsGroup, String terminalId, String cimNamespace, String euNamespace, Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         // Write the OperationalLimitSet
         String operationalLimitSetId;
         String operationalLimitSetName;
@@ -1233,30 +1226,30 @@ private static void writeLimitsGroup(Identifiable<?> identifiable, OperationalLi
         // Write the OperationalLimit objects
         Optional<ActivePowerLimits> activePowerLimits = limitsGroup.getActivePowerLimits();
         if (activePowerLimits.isPresent()) {
-            writeLoadingLimits(activePowerLimits.get(), cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, operationalLimitSetId, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeLoadingLimits(activePowerLimits.get(), cimNamespace, euNamespace, operationalLimitSetId, exportedLimitTypes, writer, context);
         }
         Optional<ApparentPowerLimits> apparentPowerLimits = limitsGroup.getApparentPowerLimits();
         if (apparentPowerLimits.isPresent()) {
-            writeLoadingLimits(apparentPowerLimits.get(), cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, operationalLimitSetId, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeLoadingLimits(apparentPowerLimits.get(), cimNamespace, euNamespace, operationalLimitSetId, exportedLimitTypes, writer, context);
         }
         Optional<CurrentLimits> currentLimits = limitsGroup.getCurrentLimits();
         if (currentLimits.isPresent()) {
-            writeLoadingLimits(currentLimits.get(), cimNamespace, euNamespace, valueAttributeName, limitTypeAttributeName, limitKindClassName, operationalLimitSetId, exportedLimitTypes, writeInfiniteDuration, writer, context);
+            writeLoadingLimits(currentLimits.get(), cimNamespace, euNamespace, operationalLimitSetId, exportedLimitTypes, writer, context);
         }
     }
 
-    private static void writeLoadingLimits(LoadingLimits limits, String cimNamespace, String euNamespace, String valueAttributeName, String limitTypeAttributeName, String limitKindClassName, String operationalLimitSetId, Set<String> exportedLimitTypes, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+    private static void writeLoadingLimits(LoadingLimits limits, String cimNamespace, String euNamespace, String operationalLimitSetId, Set<String> exportedLimitTypes, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         // Write the permanent limit type (if not already written)
         String operationalLimitTypeId = context.getNamingStrategy().getCgmesId(PATL, OPERATIONAL_LIMIT_TYPE);
         if (!exportedLimitTypes.contains(operationalLimitTypeId)) {
-            OperationalLimitTypeEq.writePatl(operationalLimitTypeId, cimNamespace, euNamespace, limitTypeAttributeName, limitKindClassName, writeInfiniteDuration, writer, context);
+            OperationalLimitTypeEq.writePatl(operationalLimitTypeId, cimNamespace, euNamespace, writer, context);
             exportedLimitTypes.add(operationalLimitTypeId);
         }
 
         // Write the permanent limit
         String className = loadingLimitClassName(limits);
         String operationalLimitId = context.getNamingStrategy().getCgmesId(ref(operationalLimitSetId), ref(className), PATL, OPERATIONAL_LIMIT_VALUE);
-        LoadingLimitEq.write(operationalLimitId, limits, "PATL", limits.getPermanentLimit(), operationalLimitTypeId, operationalLimitSetId, cimNamespace, valueAttributeName, writer, context);
+        LoadingLimitEq.write(operationalLimitId, limits, "PATL", limits.getPermanentLimit(), operationalLimitTypeId, operationalLimitSetId, cimNamespace, writer, context);
 
         if (!limits.getTemporaryLimits().isEmpty()) {
             for (LoadingLimits.TemporaryLimit temporaryLimit : limits.getTemporaryLimits()) {
@@ -1265,13 +1258,13 @@ private static void writeLoadingLimits(LoadingLimits limits, String cimNamespace
                 // Write the temporary limit type (if not already written)
                 operationalLimitTypeId = context.getNamingStrategy().getCgmesId(TATL, ref(acceptableDuration), OPERATIONAL_LIMIT_TYPE);
                 if (!exportedLimitTypes.contains(operationalLimitTypeId)) {
-                    OperationalLimitTypeEq.writeTatl(operationalLimitTypeId, temporaryLimit.getAcceptableDuration(), cimNamespace, euNamespace, limitTypeAttributeName, limitKindClassName, writeInfiniteDuration, writer, context);
+                    OperationalLimitTypeEq.writeTatl(operationalLimitTypeId, temporaryLimit.getAcceptableDuration(), cimNamespace, euNamespace, writer, context);
                     exportedLimitTypes.add(operationalLimitTypeId);
                 }
 
                 // Write the temporary limit
                 operationalLimitId = context.getNamingStrategy().getCgmesId(ref(operationalLimitSetId), ref(className), TATL, ref(acceptableDuration), OPERATIONAL_LIMIT_VALUE);
-                LoadingLimitEq.write(operationalLimitId, limits, temporaryLimit.getName(), temporaryLimit.getValue(), operationalLimitTypeId, operationalLimitSetId, cimNamespace, valueAttributeName, writer, context);
+                LoadingLimitEq.write(operationalLimitId, limits, temporaryLimit.getName(), temporaryLimit.getValue(), operationalLimitTypeId, operationalLimitSetId, cimNamespace, writer, context);
             }
         }
     }
diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/GeneratingUnitEq.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/GeneratingUnitEq.java
index acc7765f5f9..1c78a93b4ec 100644
--- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/GeneratingUnitEq.java
+++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/GeneratingUnitEq.java
@@ -26,7 +26,7 @@ public final class GeneratingUnitEq {
     private static final String EQ_GENERATINGUNIT_MAXP = "GeneratingUnit.maxOperatingP";
     private static final String EQ_GENERATINGUNIT_INITIALP = "GeneratingUnit.initialP";
 
-    public static void write(String id, String generatingUnitName, EnergySource energySource, double minP, double maxP, double initialP, String cimNamespace, boolean writeInitialP,
+    public static void write(String id, String generatingUnitName, EnergySource energySource, double minP, double maxP, double initialP, String cimNamespace,
                              String equipmentContainer, String hydroPowerPlantId, String windGenUnitType, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         CgmesExportUtil.writeStartIdName(generatingUnitClassName(energySource), id, generatingUnitName, cimNamespace, writer, context);
         writer.writeStartElement(cimNamespace, EQ_GENERATINGUNIT_MINP);
@@ -35,7 +35,7 @@ public static void write(String id, String generatingUnitName, EnergySource ener
         writer.writeStartElement(cimNamespace, EQ_GENERATINGUNIT_MAXP);
         writer.writeCharacters(CgmesExportUtil.format(maxP));
         writer.writeEndElement();
-        if (writeInitialP) {
+        if (context.getCimVersion() == 16) {
             writer.writeStartElement(cimNamespace, EQ_GENERATINGUNIT_INITIALP);
             writer.writeCharacters(CgmesExportUtil.format(initialP));
             writer.writeEndElement();
diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/LoadingLimitEq.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/LoadingLimitEq.java
index e70cd124efd..9a9086ef5e1 100644
--- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/LoadingLimitEq.java
+++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/LoadingLimitEq.java
@@ -24,10 +24,10 @@
 public final class LoadingLimitEq {
 
     public static void write(String id, LoadingLimits loadingLimits, String name, double value,
-                             String operationalLimitTypeId, String operationalLimitSetId, String cimNamespace, String valueAttributeName, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+                             String operationalLimitTypeId, String operationalLimitSetId, String cimNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         String cgmesClass = loadingLimitClassName(loadingLimits);
         CgmesExportUtil.writeStartIdName(cgmesClass, id, name, cimNamespace, writer, context);
-        writer.writeStartElement(cimNamespace, cgmesClass + "." + valueAttributeName);
+        writer.writeStartElement(cimNamespace, cgmesClass + "." + getLimitValueAttributeName(context));
         writer.writeCharacters(CgmesExportUtil.format(value));
         writer.writeEndElement();
         CgmesExportUtil.writeReference("OperationalLimit.OperationalLimitSet", operationalLimitSetId, cimNamespace, writer, context);
@@ -46,6 +46,16 @@ public static String loadingLimitClassName(LoadingLimits loadingLimits) {
         throw new PowsyblException("Unsupported loading limits " + loadingLimits.getClass().getSimpleName());
     }
 
+    public static String getLimitValueAttributeName(CgmesExportContext context) {
+        if (context.getCimVersion() == 14) {
+            throw new PowsyblException("Undefined limit value attribute name for version 14");
+        } else if (context.getCimVersion() == 16) {
+            return "value";
+        } else {
+            return "normalValue";
+        }
+    }
+
     private LoadingLimitEq() {
     }
 }
diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/OperationalLimitTypeEq.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/OperationalLimitTypeEq.java
index ed1a4bd5b8c..3f5b3d60690 100644
--- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/OperationalLimitTypeEq.java
+++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/OperationalLimitTypeEq.java
@@ -10,6 +10,7 @@
 import com.powsybl.cgmes.conversion.export.CgmesExportContext;
 import com.powsybl.cgmes.conversion.export.CgmesExportUtil;
 import com.powsybl.cgmes.model.CgmesNames;
+import com.powsybl.commons.PowsyblException;
 
 import javax.xml.stream.XMLStreamException;
 import javax.xml.stream.XMLStreamWriter;
@@ -25,22 +26,22 @@ public final class OperationalLimitTypeEq {
     private static final String PATL = "patl";
     private static final String TATL = "tatl";
 
-    public static void writePatl(String id, String cimNamespace, String euNamespace, String limitTypeAttributeName, String limitKindClassName, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+    public static void writePatl(String id, String cimNamespace, String euNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         CgmesExportUtil.writeStartIdName("OperationalLimitType", id, "PATL", cimNamespace, writer, context);
         writeDirection(cimNamespace, writer);
-        writeKind(PATL, euNamespace, limitTypeAttributeName, limitKindClassName, writer);
-        if (writeInfiniteDuration) {
+        writeKind(PATL, euNamespace, writer, context);
+        if (context.getCimVersion() == 100) {
             writeInfiniteDuration(true, cimNamespace, writer);
         }
         writer.writeEndElement();
     }
 
     public static void writeTatl(String id, int acceptableDuration, String cimNamespace, String euNamespace,
-                                 String limitTypeAttributeName, String limitKindClassName, boolean writeInfiniteDuration, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+                                 XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
         CgmesExportUtil.writeStartIdName("OperationalLimitType", id, "TATL " + acceptableDuration, cimNamespace, writer, context);
         writeDirection(cimNamespace, writer);
-        writeKind(TATL, euNamespace, limitTypeAttributeName, limitKindClassName, writer);
-        if (writeInfiniteDuration) {
+        writeKind(TATL, euNamespace, writer, context);
+        if (context.getCimVersion() == 100) {
             writeInfiniteDuration(false, cimNamespace, writer);
         }
         writer.writeStartElement(cimNamespace, "OperationalLimitType.acceptableDuration");
@@ -54,9 +55,9 @@ private static void writeDirection(String cimNamespace, XMLStreamWriter writer)
         writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, cimNamespace + ABSOLUTEVALUE_LIMITDIRECTION);
     }
 
-    private static void writeKind(String kind, String euNamespace, String limitTypeAttributeName, String limitKindClassName, XMLStreamWriter writer) throws XMLStreamException {
-        writer.writeEmptyElement(euNamespace, limitTypeAttributeName);
-        writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, String.format("%s%s.%s", euNamespace, limitKindClassName, kind));
+    private static void writeKind(String kind, String euNamespace, XMLStreamWriter writer, CgmesExportContext context) throws XMLStreamException {
+        writer.writeEmptyElement(euNamespace, getLimitTypeAttributeName(context));
+        writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, String.format("%s%s.%s", euNamespace, getLimitKindClassName(context), kind));
     }
 
     private static void writeInfiniteDuration(boolean infiniteDuration, String cimNamespace, XMLStreamWriter writer) throws XMLStreamException {
@@ -65,6 +66,26 @@ private static void writeInfiniteDuration(boolean infiniteDuration, String cimNa
         writer.writeEndElement();
     }
 
+    public static String getLimitTypeAttributeName(CgmesExportContext context) {
+        if (context.getCimVersion() == 14) {
+            throw new PowsyblException("Undefined limit type attribute name for version 14");
+        } else if (context.getCimVersion() == 16) {
+            return "OperationalLimitType.limitType";
+        } else {
+            return "OperationalLimitType.kind";
+        }
+    }
+
+    public static String getLimitKindClassName(CgmesExportContext context) {
+        if (context.getCimVersion() == 14) {
+            throw new PowsyblException("Undefined limit kind class name for version 14");
+        } else if (context.getCimVersion() == 16) {
+            return "LimitTypeKind";
+        } else {
+            return "LimitKind";
+        }
+    }
+
     private OperationalLimitTypeEq() {
     }
 }
diff --git a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/TapChangerEq.java b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/TapChangerEq.java
index a35419d45fb..378c4c42d4b 100644
--- a/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/TapChangerEq.java
+++ b/cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/elements/TapChangerEq.java
@@ -85,7 +85,7 @@ public static void writeRatio(String id, String tapChangerName, String transform
         writer.writeCharacters(CgmesExportUtil.format(stepVoltageIncrement));
         writer.writeEndElement();
         writeSteps(lowStep, highStep, neutralStep, normalStep, neutralU, ltcFlag, cimNamespace, writer);
-        if (context.getCim().writeTculControlMode()) {
+        if (context.getCimVersion() <= 16) {
             writer.writeEmptyElement(cimNamespace, "RatioTapChanger.tculControlMode");
             writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, String.format("%s%s.%s", cimNamespace, "TransformerControlMode", controlMode));
         }
diff --git a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/CgmesNamespace.java b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/CgmesNamespace.java
index 138a4c8e3a0..432548c63af 100644
--- a/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/CgmesNamespace.java
+++ b/cgmes/cgmes-model/src/main/java/com/powsybl/cgmes/model/CgmesNamespace.java
@@ -23,11 +23,11 @@
  */
 public final class CgmesNamespace {
 
-    private static final Logger LOG = LoggerFactory.getLogger(CgmesNamespace.class);
-
     private CgmesNamespace() {
     }
 
+    private static final Logger LOG = LoggerFactory.getLogger(CgmesNamespace.class);
+
     // cim14 is the CIM version corresponding to ENTSO-E Profile 1
     // It is used in this project to explore how to support future CGMES versions
     // We have sample models in cim14 and we use a different set of queries to obtain data
@@ -66,13 +66,8 @@ private CgmesNamespace() {
 
     public static final List<Cim> CIM_LIST = List.of(CIM_14, CIM_16, CIM_100);
 
-    public static boolean isValid(String ns) {
-        // Until CIM16 the CIM namespace contained the string "CIM-schema-cim<versionNumber>#"
-        // Since CIM100 the namespace seems to follow the pattern "/CIM<versionNumber>#"
-        return VALID_CIM_NAMESPACES.contains(ns) || CIM_100_PLUS_NAMESPACE_PATTERN.matcher(ns).matches();
-    }
-
     public interface Cim {
+
         int getVersion();
 
         String getNamespace();
@@ -88,26 +83,18 @@ public interface Cim {
         String getEuPrefix();
 
         String getEuNamespace();
-
-        String getLimitValueAttributeName();
-
-        String getLimitTypeAttributeName();
-
-        String getLimitKindClassName();
-
-        boolean writeLimitInfiniteDuration();
-
-        boolean writeGeneratingUnitInitialP();
-
-        boolean writeConnectivityNodes();
-
-        boolean writeTculControlMode();
     }
 
     private abstract static class AbstractCim implements Cim {
+
         private final int version;
         private final String namespace;
 
+        private AbstractCim(int version, String namespace) {
+            this.version = version;
+            this.namespace = namespace;
+        }
+
         @Override
         public int getVersion() {
             return version;
@@ -117,15 +104,14 @@ public int getVersion() {
         public String getNamespace() {
             return namespace;
         }
-
-        private AbstractCim(int version, String namespace) {
-            this.version = version;
-            this.namespace = namespace;
-        }
     }
 
     private static final class Cim14 extends AbstractCim {
 
+        private Cim14() {
+            super(14, CIM_14_NAMESPACE);
+        }
+
         @Override
         public boolean hasProfiles() {
             return false;
@@ -155,56 +141,21 @@ public String getEuPrefix() {
         public String getEuNamespace() {
             throw new PowsyblException("Undefined EU namespace for version 14");
         }
-
-        @Override
-        public String getLimitValueAttributeName() {
-            throw new PowsyblException("Undefined limit value attribute name for version 14");
-        }
-
-        @Override
-        public String getLimitTypeAttributeName() {
-            throw new PowsyblException("Undefined limit type attribute name for version 14");
-        }
-
-        @Override
-        public String getLimitKindClassName() {
-            throw new PowsyblException("Undefined limit kind class name for version 14");
-        }
-
-        @Override
-        public boolean writeLimitInfiniteDuration() {
-            return false;
-        }
-
-        @Override
-        public boolean writeGeneratingUnitInitialP() {
-            return false;
-        }
-
-        @Override
-        public boolean writeConnectivityNodes() {
-            return false;
-        }
-
-        @Override
-        public boolean writeTculControlMode() {
-            return true;
-        }
-
-        private Cim14() {
-            super(14, CIM_14_NAMESPACE);
-        }
     }
 
     private abstract static class AbstractCim16AndAbove extends AbstractCim {
 
         private final String euPrefix;
         private final String euNamespace;
-        private final String limitValueAttributeName;
-        private final String limitTypeAttributeName;
-        private final String limitKindClassName;
         private final BiMap<String, String> profiles = HashBiMap.create();
 
+        private AbstractCim16AndAbove(int version, String namespace, String euPrefix, String euNamespace, Map<String, String> profiles) {
+            super(version, namespace);
+            this.euPrefix = euPrefix;
+            this.euNamespace = euNamespace;
+            this.profiles.putAll(profiles);
+        }
+
         @Override
         public String getEuPrefix() {
             return euPrefix;
@@ -215,21 +166,6 @@ public String getEuNamespace() {
             return euNamespace;
         }
 
-        @Override
-        public String getLimitValueAttributeName() {
-            return limitValueAttributeName;
-        }
-
-        @Override
-        public String getLimitTypeAttributeName() {
-            return limitTypeAttributeName;
-        }
-
-        @Override
-        public String getLimitKindClassName() {
-            return limitKindClassName;
-        }
-
         @Override
         public boolean hasProfiles() {
             return true;
@@ -249,85 +185,41 @@ public String getProfileUri(String profile) {
         public String getProfile(String profileUri) {
             return profiles.inverse().get(profileUri);
         }
-
-        private AbstractCim16AndAbove(int version, String namespace, String euPrefix, String euNamespace,
-                                      String limitValueAttributeName, String limitTypeAttributeName,
-                                      String limitKindClassName, Map<String, String> profiles) {
-            super(version, namespace);
-            this.euPrefix = euPrefix;
-            this.euNamespace = euNamespace;
-            this.limitValueAttributeName = limitValueAttributeName;
-            this.limitTypeAttributeName = limitTypeAttributeName;
-            this.limitKindClassName = limitKindClassName;
-            this.profiles.putAll(profiles);
-        }
     }
 
     private static final class Cim16 extends AbstractCim16AndAbove {
 
-        @Override
-        public boolean writeLimitInfiniteDuration() {
-            return false;
-        }
-
-        @Override
-        public boolean writeGeneratingUnitInitialP() {
-            return true;
-        }
-
-        @Override
-        public boolean writeConnectivityNodes() {
-            return false;
-        }
-
-        @Override
-        public boolean writeTculControlMode() {
-            return true;
-        }
-
         private Cim16() {
             super(16, CIM_16_NAMESPACE, "entsoe", ENTSOE_NAMESPACE,
-                    "value",
-                    "OperationalLimitType.limitType", "LimitTypeKind",
-                    Map.of("EQ", CIM_16_EQ_PROFILE, "EQ_OP",
-                    CIM_16_EQ_OPERATION_PROFILE, "SSH", CIM_16_SSH_PROFILE, "SV",
-                    CIM_16_SV_PROFILE, "TP", CIM_16_TP_PROFILE,
-                    "EQ_BD", CIM_16_EQ_BD_PROFILE, "TP_BD", CIM_16_TP_BD_PROFILE));
+                    Map.of("EQ", CIM_16_EQ_PROFILE,
+                            "EQ_OP", CIM_16_EQ_OPERATION_PROFILE,
+                            "SSH", CIM_16_SSH_PROFILE,
+                            "SV", CIM_16_SV_PROFILE,
+                            "TP", CIM_16_TP_PROFILE,
+                            "EQ_BD", CIM_16_EQ_BD_PROFILE,
+                            "TP_BD", CIM_16_TP_BD_PROFILE));
         }
     }
 
     private static final class Cim100 extends AbstractCim16AndAbove {
 
-        @Override
-        public boolean writeLimitInfiniteDuration() {
-            return true;
-        }
-
-        @Override
-        public boolean writeGeneratingUnitInitialP() {
-            return false;
-        }
-
-        @Override
-        public boolean writeConnectivityNodes() {
-            return true;
-        }
-
-        @Override
-        public boolean writeTculControlMode() {
-            return false;
-        }
-
         private Cim100() {
             super(100, CIM_100_NAMESPACE, "eu", EU_NAMESPACE,
-                    "normalValue",
-                    "OperationalLimitType.kind", "LimitKind",
-                    Map.of("EQ", CIM_100_EQ_PROFILE, "EQ_OP", CIM_100_EQ_OPERATION_PROFILE,
-                    "SSH", CIM_100_SSH_PROFILE, "SV", CIM_100_SV_PROFILE, "TP", CIM_100_TP_PROFILE,
-                    "EQ_BD", CIM_100_EQ_BD_PROFILE));
+                    Map.of("EQ", CIM_100_EQ_PROFILE,
+                            "EQ_OP", CIM_100_EQ_OPERATION_PROFILE,
+                            "SSH", CIM_100_SSH_PROFILE,
+                            "SV", CIM_100_SV_PROFILE,
+                            "TP", CIM_100_TP_PROFILE,
+                            "EQ_BD", CIM_100_EQ_BD_PROFILE));
         }
     }
 
+    public static boolean isValid(String ns) {
+        // Until CIM16 the CIM namespace contained the string "CIM-schema-cim<versionNumber>#"
+        // Since CIM100 the namespace seems to follow the pattern "/CIM<versionNumber>#"
+        return VALID_CIM_NAMESPACES.contains(ns) || CIM_100_PLUS_NAMESPACE_PATTERN.matcher(ns).matches();
+    }
+
     public static Cim getCim(int cimVersion) {
         switch (cimVersion) {
             case 14:


Reviews:
user: login: olperr1
state: CHANGES_REQUESTED
author_association: MEMBER
submitted_at: 2025-03-03T10:12:40Z
user: login: rcourtier
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-05T09:30:18Z
user: login: rcourtier
state: COMMENTED
author_association: MEMBER
submitted_at: 2025-03-05T10:03:34Z
user: login: olperr1
state: APPROVED
author_association: MEMBER
submitted_at: 2025-03-05T13:25:19Z

Review comments:
diff_hunk: @@ -674,11 +674,11 @@ public BaseVoltageMapping.BaseVoltageSource getBaseVoltageByNominalVoltage(doubl
     }
 
     public boolean writeConnectivityNodes() {
-        boolean writeConnectivityNodes = cim.writeConnectivityNodes();
-        if (!writeConnectivityNodes) {
+        if (getCimVersion() == 100) {
+            return true;
+        } else {
             return topologyKind == CgmesTopologyKind.NODE_BREAKER;
         }
path: cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/CgmesExportContext.java
user: login: olperr1
body: This can be replaced by:
```java
return getCimVersion() == 100 || topologyKind == CgmesTopologyKind.NODE_BREAKER;
```
created_at: 2025-03-03T09:00:44Z
author_association: MEMBER
diff_hunk: @@ -674,11 +674,11 @@ public BaseVoltageMapping.BaseVoltageSource getBaseVoltageByNominalVoltage(doubl
     }
 
     public boolean writeConnectivityNodes() {
-        boolean writeConnectivityNodes = cim.writeConnectivityNodes();
-        if (!writeConnectivityNodes) {
+        if (getCimVersion() == 100) {
+            return true;
+        } else {
             return topologyKind == CgmesTopologyKind.NODE_BREAKER;
         }
path: cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/CgmesExportContext.java
user: login: rcourtier
body: Yes indeed.
I didn't bother doing it since this method will be removed in https://github.com/powsybl/powsybl-core/pull/3315, which is the sequel of that PR.
I will do it anyway to keep things as clean as possible.
created_at: 2025-03-05T09:30:14Z
author_association: MEMBER
diff_hunk: @@ -674,11 +674,11 @@ public BaseVoltageMapping.BaseVoltageSource getBaseVoltageByNominalVoltage(doubl
     }
 
     public boolean writeConnectivityNodes() {
-        boolean writeConnectivityNodes = cim.writeConnectivityNodes();
-        if (!writeConnectivityNodes) {
+        if (getCimVersion() == 100) {
+            return true;
+        } else {
             return topologyKind == CgmesTopologyKind.NODE_BREAKER;
         }
path: cgmes/cgmes-conversion/src/main/java/com/powsybl/cgmes/conversion/export/CgmesExportContext.java
user: login: rcourtier
body: done in 55af22ea6bf93d02ceeaec7e175f5b7c67e99961
created_at: 2025-03-05T10:03:34Z
author_association: MEMBER

PR comments:
user: login: sonarqubecloud[bot]
created_at: 2025-03-05T09:48:05Z
body: ## [![Quality Gate Passed](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/checks/QualityGateBadge/qg-passed-20px.png 'Quality Gate Passed')](https://sonarcloud.io/dashboard?id=com.powsybl%3Apowsybl-core&pullRequest=3307) **Quality Gate passed**  
Issues  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [7 New issues](https://sonarcloud.io/project/issues?id=com.powsybl%3Apowsybl-core&pullRequest=3307&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/accepted-16px.png '') [0 Accepted issues](https://sonarcloud.io/project/issues?id=com.powsybl%3Apowsybl-core&pullRequest=3307&issueStatuses=ACCEPTED)

Measures  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0 Security Hotspots](https://sonarcloud.io/project/security_hotspots?id=com.powsybl%3Apowsybl-core&pullRequest=3307&issueStatuses=OPEN,CONFIRMED&sinceLeakPeriod=true)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [91.8% Coverage on New Code](https://sonarcloud.io/component_measures?id=com.powsybl%3Apowsybl-core&pullRequest=3307&metric=new_coverage&view=list)  
![](https://sonarsource.github.io/sonarcloud-github-static-resources/v2/common/passed-16px.png '') [0.0% Duplication on New Code](https://sonarcloud.io/component_measures?id=com.powsybl%3Apowsybl-core&pullRequest=3307&metric=new_duplicated_lines_density&view=list)  
  
[See analysis details on SonarQube Cloud](https://sonarcloud.io/dashboard?id=com.powsybl%3Apowsybl-core&pullRequest=3307)


author_association: NONE