Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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 @@ -620,6 +620,12 @@ private Conversion.Config config(Properties p) {
getFormat(),
p,
USE_DETAILED_DC_MODEL_PARAMETER,
defaultValueConfig))
.setLogUnassignedOperationalLimits(
Parameter.readBoolean(
getFormat(),
p,
LOG_UNASSIGNED_OPERATIONAL_LIMITS_PARAMETER,
defaultValueConfig));

String namingStrategy = Parameter.readString(getFormat(), p, NAMING_STRATEGY_PARAMETER, defaultValueConfig);
Expand Down Expand Up @@ -698,6 +704,7 @@ private void copyStream(ReadOnlyDataSource from, DataSource to, String fromName,
public static final String USE_PREVIOUS_VALUES_DURING_UPDATE = "iidm.import.cgmes.use-previous-values-during-update";
public static final String REMOVE_PROPERTIES_AND_ALIASES_AFTER_IMPORT = "iidm.import.cgmes.remove-properties-and-aliases-after-import";
public static final String USE_DETAILED_DC_MODEL = "iidm.import.cgmes.use-detailed-dc-model";
public static final String LOG_UNASSIGNED_OPERATIONAL_LIMITS = "iidm.import.cgmes.log-unassigned-operational-limits";

public static final String SOURCE_FOR_IIDM_ID_MRID = "mRID";
public static final String SOURCE_FOR_IIDM_ID_RDFID = "rdfID";
Expand Down Expand Up @@ -829,6 +836,12 @@ private void copyStream(ReadOnlyDataSource from, DataSource to, String fromName,
"Use detailed DC model",
Boolean.FALSE);

private static final Parameter LOG_UNASSIGNED_OPERATIONAL_LIMITS_PARAMETER = new Parameter(
LOG_UNASSIGNED_OPERATIONAL_LIMITS,
ParameterType.BOOLEAN,
"Log unassigned cim:OperationalLimit-s",
Boolean.FALSE);

private static final List<Parameter> STATIC_PARAMETERS = List.of(
CONVERT_BOUNDARY_PARAMETER,
CONVERT_SV_INJECTIONS_PARAMETER,
Expand All @@ -851,7 +864,8 @@ private void copyStream(ReadOnlyDataSource from, DataSource to, String fromName,
CREATE_FICTITIOUS_VOLTAGE_LEVEL_FOR_EVERY_NODE_PARAMETER,
USE_PREVIOUS_VALUES_DURING_UPDATE_PARAMETER,
REMOVE_PROPERTIES_AND_ALIASES_AFTER_IMPORT_PARAMETER,
USE_DETAILED_DC_MODEL_PARAMETER);
USE_DETAILED_DC_MODEL_PARAMETER,
LOG_UNASSIGNED_OPERATIONAL_LIMITS_PARAMETER);

private final Parameter boundaryLocationParameter;
private final Parameter preProcessorsParameter;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -353,7 +353,12 @@ private void handleIssue(ConversionIssueCategory category, String what, Supplier

private static void logIssue(ConversionIssueCategory category, String what, Supplier<String> reason) {
if (LOG.isWarnEnabled()) {
LOG.warn("{}: {}. Reason: {}", category, what, reason.get());
String r = reason.get();
if (r.isEmpty()) {
LOG.warn("{}: {}", category, what);
} else {
LOG.warn("{}: {}. Reason: {}", category, what, r);
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1094,6 +1094,15 @@ public Config setUseDetailedDcModel(boolean useDetailedDcModel) {
return this;
}

public boolean isLogUnassignedOperationalLimits() {
return this.logUnassignedOperationalLimits;
}

public Config setLogUnassignedOperationalLimits(boolean logUnassignedOperationalLimits) {
this.logUnassignedOperationalLimits = logUnassignedOperationalLimits;
return this;
}

private boolean convertBoundary = false;

private boolean createBusbarSectionForEveryConnectivityNode = false;
Expand Down Expand Up @@ -1126,6 +1135,7 @@ public Config setUseDetailedDcModel(boolean useDetailedDcModel) {
private boolean usePreviousValuesDuringUpdate = false;
private boolean removePropertiesAndAliasesAfterImport = false;
private boolean useDetailedDcModel = false;
private boolean logUnassignedOperationalLimits = false;
}

private final CgmesModel cgmes;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import com.powsybl.cgmes.conversion.Context;
import com.powsybl.cgmes.conversion.Conversion;
import com.powsybl.cgmes.model.CgmesNames;
import com.powsybl.cgmes.model.CgmesTerminal;
import com.powsybl.iidm.network.*;
import com.powsybl.triplestore.api.PropertyBag;

Expand Down Expand Up @@ -46,6 +47,21 @@ public OperationalLimitConversion(PropertyBag l, Context context) {
if (isLoadingLimits()) {
if (terminalId != null) {
terminal = context.terminalMapping().findForFlowLimits(terminalId);
if (terminal == null) {
// If it is a switch Terminal we are not able to convert it
CgmesTerminal cgmesTerminal = context.cgmes().terminal(terminalId);
if (cgmesTerminal != null && CgmesNames.SWITCH_TYPES.contains(cgmesTerminal.conductingEquipmentType())) {
// note that in bus-breaker import, the Switch may not exist in IIDM if it has same from/to buses.
notAssigned("Switch", cgmesTerminal.conductingEquipment());
return;
}
// If it is a boundary Terminal we are not able to convert it
Boundary boundary = context.terminalMapping().findBoundary(terminalId);
if (boundary != null) {
notAssigned(boundary.getDanglingLine());
return;
}
}
}
if (terminal != null) {
checkAndCreateLimitsAdder(context.terminalMapping().number(terminalId), terminal.getConnectable());
Expand Down Expand Up @@ -225,6 +241,10 @@ private void checkAndCreateLimitsAdderThreeWindingsTransformers(ThreeWindingsTra

@Override
public boolean valid() {
if (notAssigned) {
// a "not assigned" log was already issued
return false;
}
if (vl == null && olga == null
&& olga1 == null
&& olga2 == null
Expand Down Expand Up @@ -438,19 +458,26 @@ private void notAssigned() {
}

private void notAssigned(Identifiable<?> eq) {
String type = p.getLocal(LIMIT_TYPE);
String typeName = p.getLocal(OPERATIONAL_LIMIT_TYPE_NAME);
String subclass = p.getLocal(OPERATIONAL_LIMIT_SUBCLASS);
Supplier<String> reason = () -> String.format(
"Not assigned for %s %s. Limit id, type, typeName, subClass, terminal : %s, %s, %s, %s, %s",
eq != null ? className(eq) : "",
eq != null ? eq.getId() : "",
id,
type,
typeName,
subclass,
terminalId);
context.pending(OPERATIONAL_LIMIT, reason);
notAssigned(eq != null ? className(eq) : "", eq != null ? eq.getId() : "");
}

private void notAssigned(String className, String id) {
this.notAssigned = true;
if (context.config().isLogUnassignedOperationalLimits()) {
String type = p.getLocal(LIMIT_TYPE);
String typeName = p.getLocal(OPERATIONAL_LIMIT_TYPE_NAME);
String subclass = p.getLocal(OPERATIONAL_LIMIT_SUBCLASS);
Supplier<String> reason = () -> String.format(
"Not assigned for %s %s. Limit id, type, typeName, subClass, terminal : %s, %s, %s, %s, %s",
className != null ? className : "",
id != null ? id : "",
id,
type,
typeName,
subclass,
terminalId);
context.pending(OPERATIONAL_LIMIT, reason);
}
}

private static String className(Identifiable<?> o) {
Expand All @@ -460,6 +487,7 @@ private static String className(Identifiable<?> o) {
s = s.substring(dot + 1);
}
s = s.replace("Impl", "");
s = s.replace("DanglingLine", "DanglingLine at boundary side");
return s;
}

Expand Down Expand Up @@ -573,6 +601,8 @@ private record OLGA(OperationalLimitsGroup operationalLimitsGroup, LoadingLimits
private final String equipmentId;
private final String limitSubclass;

private boolean notAssigned = false;

private OLGA olga;
private OLGA olga1;
private OLGA olga2;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,12 @@ public boolean valid() {
ignored("end buses are the same bus " + busId(1));
return false;
}
if ((isBoundary(1) || isBoundary(2)) && LOG.isWarnEnabled()) {
LOG.warn("Switch {} has at least one end in the boundary", id);
LOG.warn(" busId1, voltageLevel1 : {} {}", busId(1), voltageLevel(1).orElse(null));
LOG.warn(" side 1 is boundary : {}", isBoundary(1));
LOG.warn(" busId2, voltageLevel2 : {} {}", busId(2), voltageLevel(2).orElse(null));
LOG.warn(" side 2 is boundary : {}", isBoundary(2));
if ((isBoundary(1) || isBoundary(2)) && LOG.isDebugEnabled()) {
LOG.debug("Switch {} has at least one end in the boundary", id);
LOG.debug(" busId1, voltageLevel1 : {} {}", busId(1), voltageLevel(1).orElse(null));
LOG.debug(" side 1 is boundary : {}", isBoundary(1));
LOG.debug(" busId2, voltageLevel2 : {} {}", busId(2), voltageLevel(2).orElse(null));
LOG.debug(" side 2 is boundary : {}", isBoundary(2));
}
return true;
}
Expand Down Expand Up @@ -119,7 +119,7 @@ private SwitchKind kind() {
}

private void warnDanglingLineCreated() {
fixed("Dangling line with low impedance", "Connected to a boundary node");
fixed("Converted as a dangling line with zero impedance", "Connected to a boundary node");
Copy link
Member Author

Choose a reason for hiding this comment

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

I would change this to just an info log, or even debug, or even remove completely, this behavior is described in the CGMES import documentation here.

Copy link
Member

Choose a reason for hiding this comment

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

This generates a warn severity level log, which is usually used when an inconsistent or incomplete data is fixed. Here there is no inconsistency, this is the standard conversion process and it is documented as you pointed out, so I'm ok to change this to an info severity level log.
I think however it is important to keep this as an info and not a debug log, as users often tend to hide the debug logs and they might struggle to understand why their CGMES boundary switch is not visible in the IIDM switches.

}

public static void update(DanglingLine danglingLine, PropertyBag cgmesData, Context context) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,4 +60,14 @@ private boolean isConsideredAcTieFlow(String terminalId) {
boolean isDc = context.boundary().isHvdc(node);
return !isDc;
}

@Override
public void missing(String what) {
if ("name".equals(what)) {
// cim:TieFlow-s in practice do not have a name, and anyway we won't do anything with the name.
// -> do not log an issue.
return;
}
super.missing(what);
}
}
11 changes: 11 additions & 0 deletions docs/grid_exchange_formats/cgmes/import.md
Original file line number Diff line number Diff line change
Expand Up @@ -794,3 +794,14 @@ Removing properties and aliases invalidates all subsequent updates but reduces t
thereby improving performance. This option is suitable when the user does not need to preserve CGMES data for persistency purposes
or does not intend to perform further network updates.
`false` by default.

**iidm.import.cgmes.log-unassigned-operational-limits**
Optional property that defines whether a warning log should be issued for cim:OperationalLimit-s which could not be
imported into IIDM.
If the option is set to `true`, a warning is issued for not imported limits.
If the option is set to `false`, no warning is issued for not imported limits.
cim:OperationalLimit-s of type CurrentLimit, ActivePowerLimit and ApparentPowerLimit can be imported in IIDM only
if they relate to Branches (Lines, Tie-Lines, Two Windings Transformers), Dangling Lines (at network side,
limits at boundary side can not be imported), and Three Windings Transformers. For all other equipment types,
no convertion is done. This is the case for example for Switches, Generators, Loads, etc...
`false` by default.