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

Cgmes import update. Import EQ and SSH separately. ShuntCompensators #3278

Draft
wants to merge 63 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
dcce636
update loads.
marqueslanauja Oct 16, 2024
6bc53a8
Update loads
marqueslanauja Oct 16, 2024
0241870
Adjust validationUtil
marqueslanauja Oct 16, 2024
e1e04b2
Adjust FunctionalLogsTests
marqueslanauja Oct 16, 2024
3eafccf
Fix all the tests
marqueslanauja Oct 16, 2024
3884a51
Fix issues
marqueslanauja Oct 16, 2024
71bb0f0
Pretty code
marqueslanauja Oct 16, 2024
fafaf11
Pretty code
marqueslanauja Oct 16, 2024
004b824
Pretty code
marqueslanauja Oct 18, 2024
8dc44cf
update
marqueslanauja Nov 6, 2024
81954c6
Typo
marqueslanauja Nov 6, 2024
2e6657b
Typo
marqueslanauja Nov 6, 2024
cbb0f54
Updating report
marqueslanauja Nov 6, 2024
2812eec
Merge branch 'main' into cgmes_import_update_network_loads
marqueslanauja Nov 6, 2024
32559be
Merge branch 'main' into cgmes_import_update_network_transformers
marqueslanauja Nov 6, 2024
b3d0945
update voltage and angles after the update
marqueslanauja Nov 6, 2024
7e3766a
Fix code smells
marqueslanauja Nov 7, 2024
df10d15
Minor changes
marqueslanauja Nov 7, 2024
5114bde
Pretty code
marqueslanauja Nov 7, 2024
69ade84
Reduce complexity
marqueslanauja Nov 7, 2024
e4b95b3
Reduce complexity
marqueslanauja Nov 7, 2024
81376bd
Undo mistake made before
marqueslanauja Nov 7, 2024
e7da075
pretty code
marqueslanauja Nov 7, 2024
4884abb
Some improvements
marqueslanauja Nov 13, 2024
779d778
Some improvements
marqueslanauja Nov 13, 2024
cdc18f7
More improvements
marqueslanauja Nov 13, 2024
5b2796c
update by using static classes
marqueslanauja Nov 14, 2024
324c805
Remove unused methods
marqueslanauja Nov 14, 2024
160edf1
update by using static classes
marqueslanauja Nov 14, 2024
c9075ca
Update comment
marqueslanauja Nov 14, 2024
79e54ae
Fix operational limits and pretty code
marqueslanauja Nov 14, 2024
42e4a14
pretty code
marqueslanauja Nov 14, 2024
3037fc2
Merge branch 'main' into cgmes_import_update_network_loads
marqueslanauja Dec 11, 2024
90c1caa
Merge branch 'main' into cgmes_import_update_network_transformers
marqueslanauja Dec 11, 2024
cfbcdde
unitary tests
marqueslanauja Dec 11, 2024
5be3060
Merge branch 'main' into cgmes_import_update_network_loads
zamarrenolm Dec 11, 2024
a23bad2
use proposed API for network updates
zamarrenolm Dec 11, 2024
52a6c8f
Add unitary tests
marqueslanauja Dec 12, 2024
eee776c
Pretty code
marqueslanauja Dec 12, 2024
a0b8bfd
Merge branch 'main' into cgmes_import_update_network_transformers
marqueslanauja Dec 12, 2024
5968a0b
Merge branch 'cgmes_import_update_network_loads' into cgmes_import_up…
marqueslanauja Dec 12, 2024
3a5a3ae
Minor changes.
marqueslanauja Dec 12, 2024
4485ba1
Fix code smell
marqueslanauja Dec 12, 2024
b63bbcd
Clean load queries
marqueslanauja Dec 12, 2024
c3a3893
Clean transformer queries
marqueslanauja Dec 12, 2024
9409954
Improve the management of properties associated with operational limi…
marqueslanauja Dec 12, 2024
fadfa86
Merge branch 'main' into cgmes_import_update_network_transformers
marqueslanauja Jan 2, 2025
7d6b4be
remove unused update queries
marqueslanauja Jan 2, 2025
35e8d42
Merge branch 'main' into cgmes_import_update_network_transformers
marqueslanauja Jan 7, 2025
84655eb
Update generators
marqueslanauja Jan 9, 2025
0e0ee51
Merge branch 'main' into cgmes_import_update_network_generators
marqueslanauja Jan 9, 2025
67af19c
targetV adjustment
marqueslanauja Jan 10, 2025
876d15b
Clean query
marqueslanauja Jan 13, 2025
9c4add2
update staticVarCompensator
marqueslanauja Jan 13, 2025
4aa9045
pretty code
marqueslanauja Jan 13, 2025
6c41d49
Extend previous change to regulating controls
marqueslanauja Jan 14, 2025
3861d2a
Reduce complexity and additional minor changes
marqueslanauja Jan 14, 2025
a62ea64
Enhance the EQ files used in unit tests
marqueslanauja Jan 15, 2025
79204da
Improve files unit tests
marqueslanauja Jan 17, 2025
bac093a
Minor change
marqueslanauja Jan 17, 2025
ec9aac1
update shuntCompensator
marqueslanauja Jan 20, 2025
4aa84a9
Fix connect
marqueslanauja Jan 21, 2025
4a4ba56
Improvements to previous PRs
marqueslanauja Jan 22, 2025
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
Expand Up @@ -10,16 +10,13 @@
import com.google.common.jimfs.Configuration;
import com.google.common.jimfs.Jimfs;
import com.powsybl.cgmes.conversion.CgmesImport;
import com.powsybl.cgmes.conversion.CgmesModelExtension;
import com.powsybl.cgmes.model.CgmesModel;
import com.powsybl.commons.config.InMemoryPlatformConfig;
import com.powsybl.commons.datasource.ReadOnlyDataSource;
import com.powsybl.commons.datasource.ResourceDataSource;
import com.powsybl.commons.datasource.ResourceSet;
import com.powsybl.computation.ComputationManager;
import com.powsybl.computation.local.LocalComputationManager;
import com.powsybl.iidm.network.Importers;
import com.powsybl.iidm.network.Network;
import com.powsybl.iidm.network.*;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
Expand Down Expand Up @@ -74,10 +71,11 @@ void miniGridNodeBreakerMissingVoltageLevel() throws IOException {
}
assertNotNull(network);

// Check that a specific terminal has a voltage level, navigating the CGMES model
CgmesModel cgmes = network.getExtension(CgmesModelExtension.class).getCgmesModel();
// Check that a specific terminal has a voltage level, by using the alias to get the busBarSection
String terminalId = "T_BBS";
String voltageLevelId = cgmes.voltageLevel(cgmes.terminal(terminalId), cgmes.isNodeBreaker());
Connectable<?> connectable = network.getConnectable(terminalId);
BusbarSection busBarSection = (BusbarSection) connectable;
String voltageLevelId = busBarSection.getTerminal().getVoltageLevel().getId();
if (voltageLevelId == null || voltageLevelId.isEmpty()) {
fail("Missing voltage level for terminal " + terminalId);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,15 +178,15 @@
<cim:TapChanger.controlEnabled>true</cim:TapChanger.controlEnabled>
</cim:PhaseTapChangerAsymmetrical>
<cim:PhaseTapChangerSymmetrical rdf:about="#_6ebbef67-3061-4236-a6fd-6ccc4595f6c3-x">
<cim:TapChanger.step>3</cim:TapChanger.step>
<cim:TapChanger.step>9</cim:TapChanger.step>
<cim:TapChanger.controlEnabled>false</cim:TapChanger.controlEnabled>
</cim:PhaseTapChangerSymmetrical>
<cim:RatioTapChanger rdf:about="#_955d9cd0-4a10-4031-b008-60c0dc340a07">
<cim:TapChanger.step>10</cim:TapChanger.step>
<cim:TapChanger.controlEnabled>false</cim:TapChanger.controlEnabled>
</cim:RatioTapChanger>
<cim:RatioTapChanger rdf:about="#_955d9cd0-4a10-4031-b008-60c0dc340a07-x">
<cim:TapChanger.step>5</cim:TapChanger.step>
<cim:TapChanger.step>12</cim:TapChanger.step>
<cim:TapChanger.controlEnabled>false</cim:TapChanger.controlEnabled>
</cim:RatioTapChanger>
<cim:RatioTapChanger rdf:about="#_83cc66dd-8d93-4a2c-8103-f1f5a9cf7e2e">
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,21 @@ private Network importData1(ReadOnlyDataSource ds, NetworkFactory networkFactory
return new Conversion(cgmes, config(p), activatedPreProcessors(p), activatedPostProcessors(p), networkFactory).convert(conversionReportNode);
}

@Override
public void update(Network network, ReadOnlyDataSource ds, Properties p, ReportNode reportNode) {
TripleStoreOptions tripleStoreOptions = new TripleStoreOptions();
tripleStoreOptions.setQueryCatalog("-update");
ReadOnlyDataSource alternativeDataSourceForBoundary = null;
CgmesModel cgmes = CgmesModelFactory.create(
ds,
alternativeDataSourceForBoundary,
TripleStoreFactory.DEFAULT_IMPLEMENTATION,
reportNode,
tripleStoreOptions);
Conversion conversion = new Conversion(cgmes, config(p));
conversion.update(network, reportNode);
}

static class FilteredReadOnlyDataSource implements ReadOnlyDataSource {
private final ReadOnlyDataSource ds;
private final Predicate<String> filter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
*/
public final class CgmesReports {

private static final String EQUIPMENT_ID = "equipmentId";

private CgmesReports() {
}

Expand Down Expand Up @@ -51,6 +53,14 @@ public static ReportNode convertingElementTypeReport(ReportNode reportNode, Stri
.add();
}

public static ReportNode updatingElementTypeReport(ReportNode reportNode, String elementType) {
return reportNode.newReportNode()
.withMessageTemplate("updatingElementType", "Updating ${elementType}.")
.withUntypedValue("elementType", elementType)
.withSeverity(TypedValue.INFO_SEVERITY)
.add();
}

public static ReportNode fixingDanglingLinesIssuesReport(ReportNode reportNode) {
return reportNode.newReportNode()
.withMessageTemplate("fixingDanglingLinesIssues", "Fixing issues with dangling lines.")
Expand Down Expand Up @@ -84,17 +94,26 @@ public static void importedCgmesNetworkReport(ReportNode reportNode, String netw
public static void badVoltageTargetValueRegulatingControlReport(ReportNode reportNode, String eqId, double targetValue) {
reportNode.newReportNode()
.withMessageTemplate("badVoltageTargetValueRegulatingControl", "Equipment ${equipmentId} has a regulating control with bad target value for voltage: ${targetValue}.")
.withUntypedValue("equipmentId", eqId)
.withUntypedValue(EQUIPMENT_ID, eqId)
.withTypedValue("targetValue", targetValue, TypedValue.VOLTAGE)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}

public static void badTargetValueRegulatingControlReport(ReportNode reportNode, String eqId, double targetValue) {
reportNode.newReportNode()
.withMessageTemplate("badTargetValueRegulatingControl", "Equipment ${equipmentId} has a regulating control with bad target value: ${targetValue}.")
.withUntypedValue(EQUIPMENT_ID, eqId)
.withUntypedValue("targetValue", targetValue)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}

public static void badTargetDeadbandRegulatingControlReport(ReportNode reportNode, String eqId, double targetDeadband) {
reportNode.newReportNode()
.withMessageTemplate("badTargetDeadbandRegulatingControl", "Equipment ${equipmentId} has a regulating control with bad target deadband: ${targetDeadband}.")
.withUntypedValue("equipmentId", eqId)
.withTypedValue("targetDeadband", targetDeadband, TypedValue.VOLTAGE)
.withUntypedValue(EQUIPMENT_ID, eqId)
.withUntypedValue("targetDeadband", targetDeadband)
.withSeverity(TypedValue.WARN_SEVERITY)
.add();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,10 @@ public Context(CgmesModel cgmes, Config config, Network network, ReportNode repo
reactiveCapabilityCurveData = new HashMap<>();
powerTransformerRatioTapChangers = new HashMap<>();
powerTransformerPhaseTapChangers = new HashMap<>();
cgmesTerminals = new HashMap<>();
regulatingControls = new HashMap<>();
operationalLimits = new HashMap<>();
generatingUnits = new HashMap<>();
}

public CgmesModel cgmes() {
Expand Down Expand Up @@ -100,6 +104,11 @@ public void convertedTerminal(String terminalId, Terminal t, int n, PowerFlow f)
}
}

public void convertedTerminalWithOnlyEq(String terminalId, Terminal t, int n) {
// Record the mapping between CGMES and IIDM terminals
terminalMapping().add(terminalId, t, n);
}

private boolean setPQAllowed(Terminal t) {
return t.getConnectable().getType() != IdentifiableType.BUSBAR_SECTION;
}
Expand Down Expand Up @@ -205,6 +214,51 @@ public PropertyBags phaseTapChangerTable(String tableId) {
return phaseTapChangerTables.get(tableId);
}

public void loadCgmesTerminals() {
cgmes.terminals().forEach(p -> {
String id = p.getId(CgmesNames.TERMINAL);
cgmesTerminals.put(id, p);
});

}

public PropertyBag cgmesTerminal(String id) {
return cgmesTerminals.get(id);
}

public void loadRegulatingControls() {
cgmes.regulatingControls().forEach(p -> {
String id = p.getId(CgmesNames.REGULATING_CONTROL);
regulatingControls.put(id, p);
});
}

public PropertyBag regulatingControl(String id) {
return regulatingControls.get(id);
}

public void loadOperationalLimits() {
cgmes.operationalLimits().forEach(op -> {
String id = op.getId(CgmesNames.OPERATIONAL_LIMIT);
operationalLimits.put(id, op);
});
}

public PropertyBag operationalLimit(String id) {
return operationalLimits.get(id);
}

public void loadGeneratingUnits() {
cgmes.generatingUnits().forEach(generatingUnit -> {
String id = generatingUnit.getId(CgmesNames.GENERATING_UNIT);
generatingUnits.put(id, generatingUnit);
});
}

public PropertyBag generatingUnit(String id) {
return generatingUnits.get(id);
}

// Handling issues found during conversion

public ReportNode getReportNode() {
Expand Down Expand Up @@ -318,6 +372,10 @@ private static void logIssue(ConversionIssueCategory category, String what, Supp
private final Map<String, PropertyBags> reactiveCapabilityCurveData;
private final Map<String, PropertyBag> powerTransformerRatioTapChangers;
private final Map<String, PropertyBag> powerTransformerPhaseTapChangers;
private final Map<String, PropertyBag> cgmesTerminals;
private final Map<String, PropertyBag> regulatingControls;
private final Map<String, PropertyBag> operationalLimits;
private final Map<String, PropertyBag> generatingUnits;

private static final Logger LOG = LoggerFactory.getLogger(Context.class);
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
import java.util.stream.Stream;

import static com.powsybl.cgmes.conversion.Conversion.Config.StateProfile.SSH;
import static com.powsybl.cgmes.conversion.Update.*;
import static java.util.stream.Collectors.groupingBy;

/**
Expand Down Expand Up @@ -158,7 +159,14 @@ public Network convert(ReportNode reportNode) {

// Create base network with metadata information
Network network = createNetwork();
network.setMinimumAcceptableValidationLevel(ValidationLevel.EQUIPMENT);

// FIXME(Luma) we are not reusing conversion objects,
// so it is safe to store the context as an attribute for later use in update
// to do things right the context should have been created in the constructor,
// together with the empty network
Context context = createContext(network, reportNode);

assignNetworkProperties(context);
addMetadataModels(network, context);
addCimCharacteristics(network);
Expand Down Expand Up @@ -253,7 +261,7 @@ public Network convert(ReportNode reportNode) {
// Set voltages and angles
context.pushReportNode(CgmesReports.settingVoltagesAndAnglesReport(reportNode));
voltageAngles(nodes, context);
completeVoltagesAndAngles(network);
completeVoltagesAndAnglesLegacy(network);
context.popReportNode();

// Save/store data for debug or external validation
Expand All @@ -276,9 +284,64 @@ public Network convert(ReportNode reportNode) {
}

CgmesReports.importedCgmesNetworkReport(reportNode, network.getId());

// FIXME(Luma) in the first step, the Conversion object has used only info from EQ,
// we call the update method on the same conversion object,
// that has the context created during the convert (first) step
// and all the data already loaded in the triplestore,
// we only need to switch to a different set of queries
updateWithAllInputs(network, context, reportNode);

return network;
}

private void updateWithAllInputs(Network network, Context convertContext, ReportNode reportNode) {
// FIXME(Luma) Before switching to update we must invalidate all caches of the cgmes model
// and change the query catalog to "update" mode
if (!sshIncludedInCgmesModel(this.cgmes)) {
return;
}
this.cgmes.invalidateCaches();
this.cgmes.setQueryCatalog("-update");
Context updateContext = createUpdateContext(network, reportNode);

// add processes to create new equipment using update data (ssh and sv data)

update(network, updateContext, reportNode);
}

private static boolean sshIncludedInCgmesModel(CgmesModel cgmes) {
return cgmes.version().contains("CIM14") || cgmes.fullModels().stream().anyMatch(fullModel -> fullModel.getId("profileList").contains("SteadyStateHypothesis"));
}

public void update(Network network, ReportNode reportNode) {
Objects.requireNonNull(network);
Objects.requireNonNull(reportNode);
Context updateContext = createUpdateContext(network, reportNode);
update(network, updateContext, reportNode);
}

private void update(Network network, Context updateContext, ReportNode reportNode) {
// FIXME(Luma) Inspect the contents of the loaded data
if (LOG.isDebugEnabled()) {
PropertyBags nts = cgmes.numObjectsByType();
LOG.debug("CGMES objects read for the update:");
nts.forEach(nt -> LOG.debug(String.format(" %5d %s", nt.asInt("numObjects"), nt.getLocal("Type"))));
nts.forEach(nt -> LOG.debug(cgmes.allObjectsOfType(nt.getLocal("Type")).tabulateLocals()));
}

updateLoads(network, cgmes, updateContext);
updateGenerators(network, cgmes, updateContext);
updateTransformers(network, updateContext);
updateStaticVarCompensators(network, cgmes, updateContext);
updateShuntCompensators(network, cgmes, updateContext);

completeVoltagesAndAngles(network);

network.runValidationChecks(false, reportNode);
network.setMinimumAcceptableValidationLevel(ValidationLevel.STEADY_STATE_HYPOTHESIS);
}

/**
* Retrieve the Collection of OperationalLimitGroups for identifiable that have flow limits
* (branch, dangling line, 3w-transformer).
Expand Down Expand Up @@ -389,18 +452,21 @@ private Source isBoundaryBaseVoltage(String graph) {
return graph.contains("EQ") && graph.contains("BD") ? Source.BOUNDARY : Source.IGM;
}

private static void completeVoltagesAndAngles(Network network) {

// Voltage and angle in starBus as properties
network.getThreeWindingsTransformers()
.forEach(ThreeWindingsTransformerConversion::calculateVoltageAndAngleInStarBus);
private static void completeVoltagesAndAnglesLegacy(Network network) {

// Voltage and angle in boundary buses
network.getDanglingLineStream(DanglingLineFilter.UNPAIRED)
.forEach(AbstractConductingEquipmentConversion::calculateVoltageAndAngleInBoundaryBus);
network.getTieLines().forEach(tieLine -> AbstractConductingEquipmentConversion.calculateVoltageAndAngleInBoundaryBus(tieLine.getDanglingLine1(), tieLine.getDanglingLine2()));
}

private static void completeVoltagesAndAngles(Network network) {

// Voltage and angle in starBus as properties
network.getThreeWindingsTransformers()
.forEach(ThreeWindingsTransformerConversion::calculateVoltageAndAngleInStarBus);
}

private static void createControlArea(CgmesControlAreas cgmesControlAreas, PropertyBag ca) {
String controlAreaId = ca.getId("ControlArea");
cgmesControlAreas.newCgmesControlArea()
Expand Down Expand Up @@ -480,6 +546,17 @@ private Context createContext(Network network, ReportNode reportNode) {
return context;
}

private Context createUpdateContext(Network network, ReportNode reportNode) {
Context context = new Context(cgmes, config, network, reportNode);
context.loadCgmesTerminals();
context.loadRatioTapChangers();
context.loadPhaseTapChangers();
context.loadRegulatingControls();
context.loadOperationalLimits();
context.loadGeneratingUnits();
return context;
}

private void assignNetworkProperties(Context context) {
context.network().setProperty(NETWORK_PS_CGMES_MODEL_DETAIL,
context.nodeBreaker()
Expand Down Expand Up @@ -849,6 +926,13 @@ public enum StateProfile {
SV
}

public enum DefaultValue {
EQ,
DEFAULT,
EMPTY,
PREVIOUS
}

public List<String> substationIdsExcludedFromMapping() {
return Collections.emptyList();
}
Expand Down Expand Up @@ -1043,6 +1127,14 @@ public boolean disconnectNetworkSideOfDanglingLinesIfBoundaryIsDisconnected() {
return disconnectNetworkSideOfDanglingLinesIfBoundaryIsDisconnected;
}

public boolean updateTerminalConnectionInNodeBreakerVoltageLevel() {
return UPDATE_TERMINAL_CONNECTION_IN_NODE_BREAKER_VOLTAGE_LEVEL;
}

public List<DefaultValue> updateDefaultValuesPriority() {
return updateDefaultValuesPriority;
}

public boolean getCreateFictitiousVoltageLevelsForEveryNode() {
return createFictitiousVoltageLevelsForEveryNode;
}
Expand Down Expand Up @@ -1081,6 +1173,8 @@ public Config setCreateFictitiousVoltageLevelsForEveryNode(boolean b) {

private double missingPermanentLimitPercentage = 100;
private boolean createFictitiousVoltageLevelsForEveryNode = true;
private static final boolean UPDATE_TERMINAL_CONNECTION_IN_NODE_BREAKER_VOLTAGE_LEVEL = false;
private final List<DefaultValue> updateDefaultValuesPriority = List.of(DefaultValue.EQ, DefaultValue.DEFAULT, DefaultValue.EMPTY);
}

private final CgmesModel cgmes;
Expand Down
Loading
Loading