JsonCracCreationParametersConstants.java
/*
* Copyright (c) 2022, 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/.
*/
package com.powsybl.openrao.data.crac.api.parameters;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;
import com.powsybl.openrao.commons.OpenRaoException;
import com.powsybl.openrao.data.crac.api.RaUsageLimits;
import org.apache.commons.lang3.tuple.Pair;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
/**
* @author Peter Mitri {@literal <peter.mitri at rte-france.com>}
*/
public final class JsonCracCreationParametersConstants {
static final String CRAC_FACTORY = "crac-factory";
static final String DEFAULT_MONITORED_LINE_SIDE = "default-monitored-line-side";
private static final String MONITOR_LINES_ON_LEFT_SIDE_TEXT = "monitor-lines-on-left-side";
private static final String MONITOR_LINES_ON_SIDE_ONE_TEXT = "monitor-lines-on-side-one";
private static final String MONITOR_LINES_ON_RIGHT_SIDE_TEXT = "monitor-lines-on-right-side";
private static final String MONITOR_LINES_ON_SIDE_TWO_TEXT = "monitor-lines-on-side-two";
private static final String MONITOR_LINES_ON_BOTH_SIDES_TEXT = "monitor-lines-on-both-sides";
public static final String RA_USAGE_LIMITS_PER_INSTANT = "ra-usage-limits-per-instant";
public static final String INSTANT = "instant";
public static final String MAX_RA = "max-ra";
public static final String MAX_TSO = "max-tso";
public static final String MAX_TOPO_PER_TSO = "max-topo-per-tso";
public static final String MAX_PST_PER_TSO = "max-pst-per-tso";
public static final String MAX_RA_PER_TSO = "max-ra-per-tso";
public static final String MAX_ELEMENTARY_ACTIONS_PER_TSO = "max-elementary-actions-per-tso";
private JsonCracCreationParametersConstants() {
// should not be instantiated
}
static String serializeMonitoredLineSide(CracCreationParameters.MonitoredLineSide monitoredLineSide) {
return switch (monitoredLineSide) {
case MONITOR_LINES_ON_SIDE_ONE -> MONITOR_LINES_ON_SIDE_ONE_TEXT;
case MONITOR_LINES_ON_SIDE_TWO -> MONITOR_LINES_ON_SIDE_TWO_TEXT;
case MONITOR_LINES_ON_BOTH_SIDES -> MONITOR_LINES_ON_BOTH_SIDES_TEXT;
};
}
static CracCreationParameters.MonitoredLineSide deserializeMonitoredLineSide(String monitoredLineSide) {
return switch (monitoredLineSide) {
case MONITOR_LINES_ON_SIDE_ONE_TEXT, MONITOR_LINES_ON_LEFT_SIDE_TEXT ->
CracCreationParameters.MonitoredLineSide.MONITOR_LINES_ON_SIDE_ONE;
case MONITOR_LINES_ON_SIDE_TWO_TEXT, MONITOR_LINES_ON_RIGHT_SIDE_TEXT ->
CracCreationParameters.MonitoredLineSide.MONITOR_LINES_ON_SIDE_TWO;
case MONITOR_LINES_ON_BOTH_SIDES_TEXT ->
CracCreationParameters.MonitoredLineSide.MONITOR_LINES_ON_BOTH_SIDES;
default -> throw new OpenRaoException(String.format("Unknown monitored line side: %s", monitoredLineSide));
};
}
static void serializeRaUsageLimits(CracCreationParameters parameters, JsonGenerator jsonGenerator) throws IOException {
jsonGenerator.writeFieldName(RA_USAGE_LIMITS_PER_INSTANT);
jsonGenerator.writeStartArray();
for (Map.Entry<String, RaUsageLimits> entry : parameters.getRaUsageLimitsPerInstant().entrySet()) {
serializeRaUsageLimitForOneInstant(jsonGenerator, entry);
}
jsonGenerator.writeEndArray();
}
public static void serializeRaUsageLimitForOneInstant(JsonGenerator jsonGenerator, Map.Entry<String, RaUsageLimits> entry) throws IOException {
RaUsageLimits raUsageLimits = entry.getValue();
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField(INSTANT, entry.getKey());
jsonGenerator.writeNumberField(MAX_RA, raUsageLimits.getMaxRa());
jsonGenerator.writeNumberField(MAX_TSO, raUsageLimits.getMaxTso());
jsonGenerator.writeObjectField(MAX_TOPO_PER_TSO, new TreeMap<>(raUsageLimits.getMaxTopoPerTso()));
jsonGenerator.writeObjectField(MAX_PST_PER_TSO, new TreeMap<>(raUsageLimits.getMaxPstPerTso()));
jsonGenerator.writeObjectField(MAX_RA_PER_TSO, new TreeMap<>(raUsageLimits.getMaxRaPerTso()));
jsonGenerator.writeObjectField(MAX_ELEMENTARY_ACTIONS_PER_TSO, new TreeMap<>(raUsageLimits.getMaxElementaryActionsPerTso()));
jsonGenerator.writeEndObject();
}
static void deserializeRaUsageLimitsAndUpdateParameters(JsonParser jsonParser, CracCreationParameters parameters) throws IOException {
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
Pair<String, RaUsageLimits> pairOfInstantAndItsRaUsageLimits = deserializeRaUsageLimits(jsonParser);
parameters.addRaUsageLimitsForInstant(pairOfInstantAndItsRaUsageLimits.getLeft(), pairOfInstantAndItsRaUsageLimits.getRight());
}
}
private static Map<String, Integer> readStringToPositiveIntMap(JsonParser jsonParser) throws IOException {
HashMap<String, Integer> map = jsonParser.readValueAs(HashMap.class);
// Check types
map.forEach((Object o, Object o2) -> {
if (!(o instanceof String) || !(o2 instanceof Integer)) {
throw new OpenRaoException("Unexpected key or value type in a Map<String, Integer> parameter!");
}
if ((int) o2 < 0) {
throw new OpenRaoException("Unexpected negative integer!");
}
});
return map;
}
public static Pair<String, RaUsageLimits> deserializeRaUsageLimits(JsonParser jsonParser) throws IOException {
RaUsageLimits raUsageLimits = new RaUsageLimits();
String instant = null;
while (!jsonParser.nextToken().isStructEnd()) {
switch (jsonParser.getCurrentName()) {
case INSTANT:
jsonParser.nextToken();
instant = jsonParser.getValueAsString();
break;
case MAX_RA:
jsonParser.nextToken();
raUsageLimits.setMaxRa(jsonParser.getIntValue());
break;
case MAX_TSO:
jsonParser.nextToken();
raUsageLimits.setMaxTso(jsonParser.getIntValue());
break;
case MAX_TOPO_PER_TSO:
jsonParser.nextToken();
raUsageLimits.setMaxTopoPerTso(readStringToPositiveIntMap(jsonParser));
break;
case MAX_PST_PER_TSO:
jsonParser.nextToken();
raUsageLimits.setMaxPstPerTso(readStringToPositiveIntMap(jsonParser));
break;
case MAX_RA_PER_TSO:
jsonParser.nextToken();
raUsageLimits.setMaxRaPerTso(readStringToPositiveIntMap(jsonParser));
break;
case MAX_ELEMENTARY_ACTIONS_PER_TSO:
jsonParser.nextToken();
raUsageLimits.setMaxElementaryActionsPerTso(readStringToPositiveIntMap(jsonParser));
break;
default:
throw new OpenRaoException(String.format("Cannot deserialize ra-usage-limits-per-instant parameters: unexpected field in %s (%s)", RA_USAGE_LIMITS_PER_INSTANT, jsonParser.getCurrentName()));
}
}
return Pair.of(instant, raUsageLimits);
}
}