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

More robust UCTE naming strategy #3206

Merged
merged 41 commits into from
Dec 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d9b20e7
add xiidm to ucte element's id conversion
clementleclercRTE Oct 23, 2024
4d9e59d
add unique NodeId
clementleclercRTE Oct 23, 2024
7a1e787
add unique NodeId
clementleclercRTE Oct 23, 2024
0d55a0b
add unique NodeId
clementleclercRTE Oct 23, 2024
d5d9613
change getVoltageLevelCode method
clementleclercRTE Oct 28, 2024
97b572a
optimisation of checking elements
clementleclercRTE Oct 29, 2024
6a15014
create CounterNamingStrategy
clementleclercRTE Nov 12, 2024
1ce1b17
create CounterNamingStrategy
clementleclercRTE Nov 12, 2024
dadc852
change nodeCounter incrementation loop
clementleclercRTE Nov 12, 2024
f0bf333
change ElementId orderCode incrementation
clementleclercRTE Nov 12, 2024
74ad500
change UtceExporter exception
clementleclercRTE Nov 13, 2024
92ab8f9
change
clementleclercRTE Nov 13, 2024
b8f8027
add LOGGER and update with change request
clementleclercRTE Nov 18, 2024
1dec470
change dangling lines code generation
clementleclercRTE Nov 18, 2024
cd42dcd
change nodeID generation
clementleclercRTE Nov 18, 2024
609bece
delete LOGGER
clementleclercRTE Nov 19, 2024
8f159d3
code optimisation
leclerc92 Nov 21, 2024
d7f076e
add CounterNamingStrategyTest
leclerc92 Nov 21, 2024
82783ef
code review
clementleclercRTE Nov 25, 2024
4c9e246
changer danglingline getBusBreakerView()
clementleclercRTE Nov 25, 2024
bbfbee3
inverse node order for Transformaters
clementleclercRTE Nov 25, 2024
61995d8
change incrementation of namingcounter
clementleclercRTE Nov 26, 2024
45ed401
retry change incrementation of namingcounter
clementleclercRTE Nov 26, 2024
84cf3c4
change implementation
clementleclercRTE Nov 26, 2024
e618277
change OrderCode list
clementleclercRTE Dec 2, 2024
20e844c
change OrderCode list
clementleclercRTE Dec 2, 2024
9762869
change DanlingLine conversion
clementleclercRTE Dec 2, 2024
e2d11b7
add orderCode getter
clementleclercRTE Dec 2, 2024
5c20757
delete system.out
clementleclercRTE Dec 3, 2024
696ca51
delete system.out
clementleclercRTE Dec 3, 2024
f2ea4e3
Merge branch 'main' into 3191-conversion-to-ucte-format
geofjamg Dec 3, 2024
b29e7b1
update CounterNamingStategyTest
clementleclercRTE Dec 3, 2024
bfe1509
Merge remote-tracking branch 'origin/3191-conversion-to-ucte-format' …
clementleclercRTE Dec 3, 2024
5b63d1e
update danglingline xnodeCode generation
clementleclercRTE Dec 3, 2024
7c480e7
update test
clementleclercRTE Dec 3, 2024
ed79865
create fromVoltageLevel in UcteCountryCode
clementleclercRTE Dec 3, 2024
71046bb
update test
clementleclercRTE Dec 9, 2024
444b327
add Exception for null equipement
clementleclercRTE Dec 9, 2024
1b686ae
add Exception for null equipment
clementleclercRTE Dec 9, 2024
930add0
fix checkstyle error
clementleclercRTE Dec 9, 2024
7e109f4
Merge branch 'main' into 3191-conversion-to-ucte-format
olperr1 Dec 16, 2024
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/**
* 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.ucte.converter;

import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.ucte.converter.util.UcteConverterConstants;
import com.powsybl.ucte.network.UcteElementId;
import com.powsybl.ucte.network.UcteNodeCode;

import java.util.HashMap;
import java.util.Map;

/**
* @author Clément LECLERC {@literal <[email protected]>}
*/
public abstract class AbstractNamingStrategy implements NamingStrategy {

protected final Map<String, UcteNodeCode> ucteNodeIds = new HashMap<>();
protected final Map<String, UcteElementId> ucteElementIds = new HashMap<>();

@Override
public void initializeNetwork(Network network) {
//Empty implementation by default
}

@Override
public UcteNodeCode getUcteNodeCode(String id) {
return ucteNodeIds.computeIfAbsent(id, k -> UcteNodeCode.parseUcteNodeCode(k)
.orElseThrow(() -> new UcteException(UcteConverterConstants.NO_UCTE_CODE_ERROR + k)));
}

@Override
public UcteNodeCode getUcteNodeCode(Bus bus) {
if (bus == null) {
throw new PowsyblException("the bus is null");
}
return getUcteNodeCode(bus.getId());
}

@Override
public UcteNodeCode getUcteNodeCode(DanglingLine danglingLine) {
if (danglingLine.getPairingKey() == null) {
return getUcteNodeCode(danglingLine.getId());
}
return getUcteNodeCode(danglingLine.getPairingKey());
}

@Override
public UcteElementId getUcteElementId(String id) {
return ucteElementIds.computeIfAbsent(id, k -> UcteElementId.parseUcteElementId(k)
.orElseThrow(() -> new UcteException(UcteConverterConstants.NO_UCTE_CODE_ERROR + k)));
}

@Override
public UcteElementId getUcteElementId(Switch sw) {
if (sw == null) {
throw new PowsyblException("the switch is null");
}
return getUcteElementId(sw.getId());
}

@Override
public UcteElementId getUcteElementId(Branch branch) {
if (branch == null) {
throw new PowsyblException("the branch is null");
}
return getUcteElementId(branch.getId());
}

@Override
public UcteElementId getUcteElementId(DanglingLine danglingLine) {
if (danglingLine == null) {
throw new PowsyblException("the danglingLine is null");
}
return getUcteElementId(danglingLine.getId());
}
}

Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
/**
* 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.ucte.converter;
clementleclercRTE marked this conversation as resolved.
Show resolved Hide resolved

import com.google.auto.service.AutoService;
import com.powsybl.iidm.network.*;
import com.powsybl.ucte.network.UcteCountryCode;
import com.powsybl.ucte.network.UcteElementId;
import com.powsybl.ucte.network.UcteNodeCode;
import com.powsybl.ucte.network.UcteVoltageLevelCode;
import com.powsybl.ucte.network.util.UcteNetworkUtil;

import java.util.*;

/**
* @author Clément LECLERC {@literal <[email protected]>}
*/
@AutoService(NamingStrategy.class)
public class CounterNamingStrategy extends AbstractNamingStrategy {

private int voltageLevelCounter;

@Override
public String getName() {
return "Counter";
}

@Override
public void initializeNetwork(Network network) {
voltageLevelCounter = 0;
network.getVoltageLevelStream()
.forEach(this::processVoltageLevel);

network.getBranchStream().forEach(this::generateUcteElementId);
network.getDanglingLineStream().forEach(this::generateUcteElementId);
}

private void processVoltageLevel(VoltageLevel voltageLevel) {
Iterator<Bus> buslist = voltageLevel.getBusBreakerView().getBuses().iterator();
for (int i = 0; buslist.hasNext(); i++) {
Bus bus = buslist.next();
char orderCode = UcteNetworkUtil.getOrderCode(i);
generateUcteNodeId(bus.getId(), voltageLevel, orderCode);
}

voltageLevel.getBusBreakerView().getSwitches()
.forEach(this::generateUcteElementId);
voltageLevelCounter++;
}

private UcteNodeCode generateUcteNodeId(String busId, VoltageLevel voltageLevel, char orderCode) {
if (UcteNodeCode.isUcteNodeId(busId)) {
return changeOrderCode(busId, orderCode);
}
return createNewUcteNodeId(busId, voltageLevel, orderCode);
}

private UcteNodeCode changeOrderCode(String busId, char orderCode) {
UcteNodeCode newNodeCode = UcteNodeCode.parseUcteNodeCode(busId).orElseThrow();
newNodeCode.setBusbar(orderCode);
ucteNodeIds.put(busId, newNodeCode);
return newNodeCode;
}

private UcteNodeCode createNewUcteNodeId(String busId, VoltageLevel voltageLevel, char orderCode) {
String newNodeId = String.format("%05d", voltageLevelCounter);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we can use [A-Z0-9] codes instead?
We could convert the number in base 36, but I think it would be better to have the letters first instead of the digits.
(=> AAAAA to AAAAZ, AAAA0 to AAAA9, then AAAABA...)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(But it is not required.)

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With numbers is ok for now. Let's see that later if one day needed.

char countryCode = UcteCountryCode.fromVoltagelevel(voltageLevel).getUcteCode();
char voltageLevelCode = UcteVoltageLevelCode.voltageLevelCodeFromVoltage(voltageLevel.getNominalV());

UcteNodeCode ucteNodeCode = new UcteNodeCode(
UcteCountryCode.fromUcteCode(countryCode),
newNodeId,
UcteVoltageLevelCode.voltageLevelCodeFromChar(voltageLevelCode),
orderCode);

ucteNodeIds.put(busId, ucteNodeCode);
return ucteNodeCode;
}

private UcteElementId generateUcteElementId(String id, UcteNodeCode node1, UcteNodeCode node2) {
if (ucteElementIds.containsKey(id)) {
return ucteElementIds.get(id);
}

UcteElementId uniqueElementId = UcteNetworkUtil.ORDER_CODES.stream()
.map(orderCode -> new UcteElementId(node1, node2, orderCode))
.filter(elementId -> !ucteElementIds.containsValue(elementId))
.findFirst()
.orElseThrow(() -> new UcteException("Unable to generate unique element ID"));

ucteElementIds.put(id, uniqueElementId);
return uniqueElementId;
}

private UcteElementId generateUcteElementId(Branch<?> branch) {
if (ucteElementIds.containsKey(branch.getId())) {
return ucteElementIds.get(branch.getId());
}
UcteNodeCode node1 = ucteNodeIds.get(branch.getTerminal1().getBusBreakerView().getBus().getId());
UcteNodeCode node2 = ucteNodeIds.get(branch.getTerminal2().getBusBreakerView().getBus().getId());

return generateUcteElementId(branch.getId(), node1, node2);
}

private UcteElementId generateUcteElementId(DanglingLine danglingLine) {
if (ucteElementIds.containsKey(danglingLine.getId())) {
return ucteElementIds.get(danglingLine.getId());
}

UcteNodeCode code1;
UcteNodeCode code2;

code1 = getUcteNodeCode(danglingLine.getTerminal().getBusBreakerView().getBus());
olperr1 marked this conversation as resolved.
Show resolved Hide resolved

if (danglingLine.getPairingKey() != null && UcteNodeCode.isUcteNodeId(danglingLine.getPairingKey())) {
code2 = UcteNodeCode.parseUcteNodeCode(danglingLine.getPairingKey()).orElseThrow();
ucteNodeIds.put(danglingLine.getPairingKey(), code2);
} else {
code2 = generateUcteNodeId(danglingLine.getId(), danglingLine.getTerminal().getVoltageLevel(), UcteNetworkUtil.getOrderCode(0));
}
return generateUcteElementId(danglingLine.getId(), code1, code2);
}

private UcteElementId generateUcteElementId(Switch sw) {
if (ucteElementIds.containsKey(sw.getId())) {
return ucteElementIds.get(sw.getId());
}

VoltageLevel.BusBreakerView view = sw.getVoltageLevel().getBusBreakerView();
Bus bus1 = view.getBus1(sw.getId());
Bus bus2 = view.getBus2(sw.getId());

UcteNodeCode u1 = getUcteNodeCode(bus1.getId());
UcteNodeCode u2 = getUcteNodeCode(bus2.getId());

return generateUcteElementId(sw.getId(), u1, u2);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -9,63 +9,18 @@
package com.powsybl.ucte.converter;

import com.google.auto.service.AutoService;
import com.powsybl.iidm.network.*;
import com.powsybl.ucte.network.UcteElementId;
import com.powsybl.ucte.network.UcteNodeCode;

import java.util.HashMap;
import java.util.Map;

/**
* A {@link NamingStrategy} implementation that ensures the conformity of IDs with the UCTE-DEF format
*
* @author Mathieu Bague {@literal <[email protected]>}
*/
@AutoService(NamingStrategy.class)
public class DefaultNamingStrategy implements NamingStrategy {

private final Map<String, UcteNodeCode> ucteNodeIds = new HashMap<>();

private final Map<String, UcteElementId> ucteElementIds = new HashMap<>();
public class DefaultNamingStrategy extends AbstractNamingStrategy {

@Override
public String getName() {
return "Default";
}

@Override
public UcteNodeCode getUcteNodeCode(String id) {
return ucteNodeIds.computeIfAbsent(id, k -> UcteNodeCode.parseUcteNodeCode(k).orElseThrow(() -> new UcteException("Invalid UCTE node identifier: " + k)));
}

@Override
public UcteNodeCode getUcteNodeCode(Bus bus) {
return getUcteNodeCode(bus.getId());
}

@Override
public UcteNodeCode getUcteNodeCode(DanglingLine danglingLine) {
return getUcteNodeCode(danglingLine.getPairingKey());
}

@Override
public UcteElementId getUcteElementId(String id) {
return ucteElementIds.computeIfAbsent(id, k -> UcteElementId.parseUcteElementId(k).orElseThrow(() -> new UcteException("Invalid UCTE node identifier: " + k)));
}

@Override
public UcteElementId getUcteElementId(Switch sw) {
return getUcteElementId(sw.getId());
}

@Override
public UcteElementId getUcteElementId(Branch branch) {
return getUcteElementId(branch.getId());
}

@Override
public UcteElementId getUcteElementId(DanglingLine danglingLine) {
return getUcteElementId(danglingLine.getId());
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
public interface NamingStrategy {

void initializeNetwork(Network network);

String getName();

UcteNodeCode getUcteNodeCode(String id);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
import java.util.*;
import java.util.function.Supplier;

import static com.powsybl.ucte.converter.util.UcteConstants.*;
import static com.powsybl.ucte.converter.util.UcteConverterConstants.*;
import static com.powsybl.ucte.converter.util.UcteConverterHelper.*;

/**
Expand Down Expand Up @@ -87,6 +87,7 @@ public void export(Network network, Properties parameters, DataSource dataSource

String namingStrategyName = Parameter.readString(getFormat(), parameters, NAMING_STRATEGY_PARAMETER, defaultValueConfig);
NamingStrategy namingStrategy = findNamingStrategy(namingStrategyName, NAMING_STRATEGY_SUPPLIERS.get());
namingStrategy.initializeNetwork(network);
boolean combinePhaseAngleRegulation = Parameter.readBoolean(getFormat(), parameters, COMBINE_PHASE_ANGLE_REGULATION_PARAMETER, defaultValueConfig);

UcteNetwork ucteNetwork = createUcteNetwork(network, namingStrategy, combinePhaseAngleRegulation);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

import static com.powsybl.ucte.converter.util.UcteConstants.*;
import static com.powsybl.ucte.converter.util.UcteConverterConstants.*;

/**
* @author Geoffroy Jamgotchian {@literal <geoffroy.jamgotchian at rte-france.com>}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@
/**
* @author Sebastien Murgey {@literal <sebastien.murgey at rte-france.com>}
*/
public final class UcteConstants {
public final class UcteConverterConstants {

private UcteConstants() {
private UcteConverterConstants() {
throw new IllegalStateException("Should not be constructed");
}

Expand All @@ -26,4 +26,5 @@ private UcteConstants() {
public static final String ORDER_CODE = "orderCode";
public static final String POWER_PLANT_TYPE_PROPERTY_KEY = "powerPlantType";
public static final int DEFAULT_POWER_LIMIT = 9999;
public static final String NO_UCTE_CODE_ERROR = "No UCTE code found for id: ";
}
Loading
Loading