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 export to version 3 #1998

Merged
merged 11 commits into from
Mar 29, 2022
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ public class CgmesExportContext {
private CgmesTopologyKind topologyKind = CgmesTopologyKind.BUS_BRANCH;
private DateTime scenarioTime = DateTime.now();

private ModelDescription eqModelDescription = new ModelDescription("EQ Model", CgmesNamespace.EQ_PROFILE);
private ModelDescription tpModelDescription = new ModelDescription("TP Model", CgmesNamespace.TP_PROFILE);
private ModelDescription svModelDescription = new ModelDescription("SV Model", CgmesNamespace.SV_PROFILE);
private ModelDescription sshModelDescription = new ModelDescription("SSH Model", CgmesNamespace.SSH_PROFILE);
private ModelDescription eqModelDescription = new ModelDescription("EQ Model", CgmesNamespace.getProfile(cimVersion, "EQ"));
private ModelDescription tpModelDescription = new ModelDescription("TP Model", CgmesNamespace.getProfile(cimVersion, "TP"));
private ModelDescription svModelDescription = new ModelDescription("SV Model", CgmesNamespace.getProfile(cimVersion, "SV"));
private ModelDescription sshModelDescription = new ModelDescription("SSH Model", CgmesNamespace.getProfile(cimVersion, "SSH"));

private boolean exportBoundaryPowerFlows = true;
private boolean exportFlowsForSwitches = false;
Expand Down Expand Up @@ -111,6 +111,11 @@ public ModelDescription setModelingAuthoritySet(String modelingAuthoritySet) {
public String getProfile() {
return profile;
}

public ModelDescription setProfile(String profile) {
this.profile = profile;
return this;
}
}

interface TopologicalConsumer {
Expand Down Expand Up @@ -512,6 +517,12 @@ public int getCimVersion() {

public CgmesExportContext setCimVersion(int cimVersion) {
this.cimVersion = cimVersion;
if (CgmesNamespace.hasProfiles(cimVersion)) {
eqModelDescription.setProfile(CgmesNamespace.getProfile(cimVersion, "EQ"));
tpModelDescription.setProfile(CgmesNamespace.getProfile(cimVersion, "TP"));
svModelDescription.setProfile(CgmesNamespace.getProfile(cimVersion, "SV"));
sshModelDescription.setProfile(CgmesNamespace.getProfile(cimVersion, "SSH"));
}
return this;
}

Expand Down Expand Up @@ -568,7 +579,7 @@ public CgmesExportContext setExportFlowsForSwitches(boolean exportFlowsForSwitch
}

public String getCimNamespace() {
return CgmesNamespace.getCimNamespace(cimVersion);
return CgmesNamespace.getCim(cimVersion);
}

public Set<CgmesIidmMapping.CgmesTopologicalNode> getTopologicalNodesByBusViewBus(String busId) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import com.powsybl.cgmes.conversion.export.CgmesExportContext.ModelDescription;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.cgmes.model.CgmesNamespace;
import com.powsybl.commons.PowsyblException;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.extensions.LoadDetail;
Expand Down Expand Up @@ -65,12 +66,12 @@ public static String getUniqueId() {
public static void writeRdfRoot(int cimVersion, XMLStreamWriter writer) throws XMLStreamException {
writer.setPrefix("entsoe", ENTSOE_NAMESPACE);
writer.setPrefix("rdf", RDF_NAMESPACE);
writer.setPrefix("cim", getCimNamespace(cimVersion));
writer.setPrefix("cim", CgmesNamespace.getCim(cimVersion));
writer.setPrefix("md", MD_NAMESPACE);
writer.writeStartElement(RDF_NAMESPACE, "RDF");
writer.writeNamespace("entsoe", ENTSOE_NAMESPACE);
writer.writeNamespace("rdf", RDF_NAMESPACE);
writer.writeNamespace("cim", getCimNamespace(cimVersion));
writer.writeNamespace("cim", CgmesNamespace.getCim(cimVersion));
writer.writeNamespace("md", MD_NAMESPACE);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ public static void write(Network network, XMLStreamWriter writer, CgmesExportCon
String cimNamespace = context.getCimNamespace();

// TODO fill EQ Model Description
if (context.getCimVersion() == 16) {
if (context.getCimVersion() >= 16) {
ModelDescriptionEq.write(writer, context.getEqModelDescription(), context);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
* @author Marcos de Miguel <demiguelm at aia.es>
*/
public final class ControlAreaEq {
private static final String CONTROL_AREA_TYPE = "http://iec.ch/TC57/2013/CIM-schema-cim16#ControlAreaTypeKind.Interchange";
private static final String CONTROL_AREA_TYPE = "ControlAreaTypeKind.Interchange";

public static void write(String id, String controlAreaName, String energyIdentificationCodeEIC, String cimNamespace, XMLStreamWriter writer) throws XMLStreamException {
writer.writeStartElement(cimNamespace, "ControlArea");
Expand All @@ -30,7 +30,7 @@ public static void write(String id, String controlAreaName, String energyIdentif
writer.writeCharacters(energyIdentificationCodeEIC);
writer.writeEndElement();
writer.writeEmptyElement(cimNamespace, "ControlArea.type");
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, CONTROL_AREA_TYPE);
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, cimNamespace + CONTROL_AREA_TYPE);
miovd marked this conversation as resolved.
Show resolved Hide resolved
writer.writeEndElement();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ public static void write(XMLStreamWriter writer, CgmesExportContext.ModelDescrip
writer.writeCharacters(modelDescription.getProfile());
writer.writeEndElement();
writer.writeStartElement(MD_NAMESPACE, CgmesNames.PROFILE);
writer.writeCharacters(CgmesNamespace.EQ_OPERATION_PROFILE);
writer.writeCharacters(CgmesNamespace.getProfile(context.getCimVersion(), "EQ_OP"));
writer.writeEndElement();
writer.writeStartElement(MD_NAMESPACE, CgmesNames.MODELING_AUTHORITY_SET);
writer.writeCharacters(modelDescription.getModelingAuthoritySet());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
*/
public final class RegulatingControlEq {

public static final String REGULATING_CONTROL_VOLTAGE = "http://iec.ch/TC57/2013/CIM-schema-cim16#RegulatingControlModeKind.voltage";
public static final String REGULATING_CONTROL_VOLTAGE = "RegulatingControlModeKind.voltage";

public static void write(String id, String regulatingControlName, String terminalId, String cimNamespace, XMLStreamWriter writer) throws XMLStreamException {
writer.writeStartElement(cimNamespace, "RegulatingControl");
Expand All @@ -29,7 +29,7 @@ public static void write(String id, String regulatingControlName, String termina
writer.writeEmptyElement(cimNamespace, "RegulatingControl.Terminal");
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, "#" + terminalId);
writer.writeEmptyElement(cimNamespace, "RegulatingControl.mode");
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, REGULATING_CONTROL_VOLTAGE);
writer.writeAttribute(RDF_NAMESPACE, CgmesNames.RESOURCE, cimNamespace + REGULATING_CONTROL_VOLTAGE);
miovd marked this conversation as resolved.
Show resolved Hide resolved
writer.writeEndElement();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import com.powsybl.cgmes.extensions.CgmesSvMetadataAdder;
import com.powsybl.cgmes.extensions.CgmesTopologyKind;
import com.powsybl.cgmes.extensions.CimCharacteristicsAdder;
import com.powsybl.cgmes.model.CgmesNamespace;
import com.powsybl.commons.datasource.ReadOnlyDataSource;
import com.powsybl.iidm.network.*;
import com.powsybl.iidm.network.test.EurostagTutorialExample1Factory;
Expand All @@ -25,8 +26,6 @@
import java.util.List;
import java.util.Properties;

import static com.powsybl.cgmes.model.CgmesNamespace.CIM_14_NAMESPACE;
import static com.powsybl.cgmes.model.CgmesNamespace.CIM_16_NAMESPACE;
import static org.junit.Assert.*;

/**
Expand All @@ -48,7 +47,7 @@ public void networkConstructor() {
CgmesExportContext context1 = new CgmesExportContext(network);

assertEquals(16, context1.getCimVersion());
assertEquals(CIM_16_NAMESPACE, context1.getCimNamespace());
assertEquals(CgmesNamespace.getCim(16), context1.getCimNamespace());
assertEquals(CgmesTopologyKind.BUS_BRANCH, context1.getTopologyKind());
assertEquals(network.getCaseDate(), context1.getScenarioTime());
assertEquals("SV Model", context1.getSvModelDescription().getDescription());
Expand All @@ -71,7 +70,7 @@ public void networkConstructor() {
CgmesExportContext context2 = new CgmesExportContext(network);

assertEquals(14, context2.getCimVersion());
assertEquals(CIM_14_NAMESPACE, context2.getCimNamespace());
assertEquals(CgmesNamespace.getCim(14), context2.getCimNamespace());
assertEquals(CgmesTopologyKind.NODE_BREAKER, context2.getTopologyKind());
assertEquals(network.getCaseDate(), context2.getScenarioTime());
assertEquals("test", context2.getSvModelDescription().getDescription());
Expand All @@ -86,7 +85,7 @@ public void networkConstructor() {
public void emptyConstructor() {
CgmesExportContext context = new CgmesExportContext();
assertEquals(16, context.getCimVersion());
assertEquals(CIM_16_NAMESPACE, context.getCimNamespace());
assertEquals(CgmesNamespace.getCim(16), context.getCimNamespace());
assertEquals(CgmesTopologyKind.BUS_BRANCH, context.getTopologyKind());
assertTrue(new Duration(DateTime.now(), context.getScenarioTime()).getStandardMinutes() < 1);
assertEquals("SV Model", context.getSvModelDescription().getDescription());
Expand All @@ -112,7 +111,7 @@ public void getSet() {
.setModelingAuthoritySet("cgmes.org");

assertEquals(14, context.getCimVersion());
assertEquals(CIM_14_NAMESPACE, context.getCimNamespace());
assertEquals(CgmesNamespace.getCim(14), context.getCimNamespace());
assertEquals(CgmesTopologyKind.NODE_BREAKER, context.getTopologyKind());
assertEquals(DateTime.parse("2020-09-22T17:21:11.381+02:00"), context.getScenarioTime());
assertEquals("test", context.getSvModelDescription().getDescription());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,20 +44,50 @@ public void testExportDataSourceEmptyBaseName() throws IOException {

@Test
public void testExportIEEE14Cim14ToCim16() {
testExportToCim(ieee14Cim14(), "IEEE14", 16);
}

@Test
public void testExportIEEE14Cim14ToCim100() {
// Testing export to CGMES 3
// TODO(Luma) verify that all classes and attributes are valid against profiles (using CIMdesk)
// TODO(Luma) Check mRID is exported
// TODO(Luma) Check GeneratingUnit.initialP (removed in CIM100)
// TODO(Luma) Check the way OperationalLimit TypeName is read
// TODO(Luma) Check OperationalLimit value (renamed to normalValue in CIM100)
Network network = ieee14Cim14();
assertEquals(14, network.getExtension(CimCharacteristics.class).getCimVersion());
testExportToCim(network, "IEEE14", 100);
}

private Network ieee14Cim14() {
ReadOnlyDataSource dataSource = Cim14SmallCasesCatalog.ieee14().dataSource();
Network networkCim14 = new CgmesImport().importData(dataSource, NetworkFactory.findDefault(), null);
CimCharacteristics cim14 = networkCim14.getExtension(CimCharacteristics.class);
return new CgmesImport().importData(dataSource, NetworkFactory.findDefault(), null);
}

private void testExportToCim(Network network, String name, int cimVersion) {
String cimZipFilename = name + "_CIM" + cimVersion;
Properties params = new Properties();
params.put(CgmesExport.CIM_VERSION, "16");
ZipFileDataSource zipIEEE14Cim16 = new ZipFileDataSource(tmpDir.resolve("."), "IEEE14");
new CgmesExport().export(networkCim14, params, zipIEEE14Cim16);
params.put(CgmesExport.CIM_VERSION, Integer.toString(cimVersion));
ZipFileDataSource zip = new ZipFileDataSource(tmpDir.resolve("."), cimZipFilename);
new CgmesExport().export(network, params, zip);

Network networkCim16 = Importers.loadNetwork(tmpDir.resolve("IEEE14.zip"));
CimCharacteristics cim16 = networkCim16.getExtension(CimCharacteristics.class);
// Reimport and verify contents of Network
Network networkCimVersion = Importers.loadNetwork(tmpDir.resolve(cimZipFilename + ".zip"));
CimCharacteristics cim = networkCimVersion.getExtension(CimCharacteristics.class);

assertEquals(14, cim14.getCimVersion());
assertEquals(16, cim16.getCimVersion());
assertEquals(cimVersion, cim.getCimVersion());
// Initial verification: check that we have the same number of elements in both networks
// TODO(Luma) compare the networks
// If the original was bus-branch (like IEEE14) and the exported is node-breaker at least compare attributes
// or select another network for verification (SmallGrid ?)
assertEquals(network.getSubstationCount(), networkCimVersion.getSubstationCount());
assertEquals(network.getVoltageLevelCount(), networkCimVersion.getVoltageLevelCount());
assertEquals(network.getLineCount(), networkCimVersion.getLineCount());
assertEquals(network.getTwoWindingsTransformerCount(), networkCimVersion.getTwoWindingsTransformerCount());
assertEquals(network.getThreeWindingsTransformerCount(), networkCimVersion.getThreeWindingsTransformerCount());
assertEquals(network.getGeneratorCount(), networkCimVersion.getGeneratorCount());
assertEquals(network.getLoadCount(), networkCimVersion.getLoadCount());
assertEquals(network.getShuntCompensatorCount(), networkCimVersion.getShuntCompensatorCount());
}

}
Loading