Skip to content

Commit

Permalink
Csa 25 voltage ra in crac api (#775)
Browse files Browse the repository at this point in the history
* [CSA-25] Implement voltage remedial actions in crac API

* [CSA-25] Removed unused imports

* [CSA-25] Fixed indentation level

* [CSA-25] Fixed Unit Tests

* [CSA-25] Fixed Linter Issues

* [CSA-25] Fixed Linter Issues

* [CSA-25] Fixed version rule for voltage constraint

* [CSA-25] Fixed null pointer exception bug

* [CSA-25] Cumulative Fixes following code review on Pull Request #775 by MarthinBelthle

* [CSA-25] Fixed Line Feed / Carriage Returns issues on windows hosts

* [CSA-25] Added unit test on VoltageConstraintAdder for increased code coverage

* [CSA-25] Cumulative enhancements

---------

Co-authored-by: Fabrice Buscaylet <fabrice.buscaylet@artelys.com>
Co-authored-by: Gabriel Plante <gabriel.plante@artelys.com>
Co-authored-by: snoopfab <snoopfab@hotmail.com>
  • Loading branch information
4 people authored Aug 3, 2023
1 parent def548b commit d2d0e70
Show file tree
Hide file tree
Showing 28 changed files with 1,032 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ void roundTripOnVoltageMonitoringParameters() throws IOException {
String exportedString = os.toString();

InputStream inputStream = getClass().getResourceAsStream("/parameters/voltage-cnecs-creation-parameters-for-round-trip.json");
assertEquals(new String(inputStream.readAllBytes()), exportedString);
assertEquals(new String(inputStream.readAllBytes()).replaceAll("\r", ""), exportedString.replaceAll("\r", ""));
}

@ParameterizedTest
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,14 @@ public final class JsonSerializationConstants {
private JsonSerializationConstants() {
}

public static final String CRAC_IO_VERSION = "1.6";
public static final String CRAC_IO_VERSION = "1.7";
/*
v1.1: addition of switchPairs
v1.2: addition of injectionRangeAction
v1.3: addition of hvdcRangeAction's and injectionRangeAction's initial setpoints
v1.4: addition of AngleCnecs; frm renamed to reliabilityMargin
v1.5: addition of VoltageCnecs
v1.7: addition of VoltageConstraints usage rules
*/

// headers
Expand Down Expand Up @@ -70,6 +71,8 @@ private JsonSerializationConstants() {

public static final String VOLTAGE_CNECS = "voltageCnecs";

public static final String VOLTAGE_CNEC_ID = "voltageCnecId";

public static final String THRESHOLDS = "thresholds";
public static final String RELIABILITY_MARGIN = "reliabilityMargin";
public static final String FRM = "frm";
Expand All @@ -95,6 +98,7 @@ private JsonSerializationConstants() {
public static final String ON_STATE_USAGE_RULES = "onStateUsageRules"; // retro-compatibility only
public static final String ON_FLOW_CONSTRAINT_USAGE_RULES = "onFlowConstraintUsageRules";
public static final String ON_ANGLE_CONSTRAINT_USAGE_RULES = "onAngleConstraintUsageRules";
public static final String ON_VOLTAGE_CONSTRAINT_USAGE_RULES = "onVoltageConstraintUsageRules";
public static final String ON_FLOW_CONSTRAINT_IN_COUNTRY_USAGE_RULES = "onFlowConstraintInCountryUsageRules";

public static final String ID = "id";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ public static void deserialize(JsonParser jsonParser, DeserializationContext des
jsonParser.nextToken();
OnAngleConstraintArrayDeserializer.deserialize(jsonParser, hvdcRangeActionAdder);
break;
case ON_VOLTAGE_CONSTRAINT_USAGE_RULES:
jsonParser.nextToken();
OnVoltageConstraintArrayDeserializer.deserialize(jsonParser, hvdcRangeActionAdder);
break;
case ON_FLOW_CONSTRAINT_IN_COUNTRY_USAGE_RULES:
jsonParser.nextToken();
OnFlowConstraintInCountryArrayDeserializer.deserialize(jsonParser, hvdcRangeActionAdder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,10 @@ public static void deserialize(JsonParser jsonParser, DeserializationContext des
jsonParser.nextToken();
OnAngleConstraintArrayDeserializer.deserialize(jsonParser, injectionRangeActionAdder);
break;
case ON_VOLTAGE_CONSTRAINT_USAGE_RULES:
jsonParser.nextToken();
OnVoltageConstraintArrayDeserializer.deserialize(jsonParser, injectionRangeActionAdder);
break;
case ON_FLOW_CONSTRAINT_IN_COUNTRY_USAGE_RULES:
jsonParser.nextToken();
OnFlowConstraintInCountryArrayDeserializer.deserialize(jsonParser, injectionRangeActionAdder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ public static void deserialize(JsonParser jsonParser, DeserializationContext des
jsonParser.nextToken();
OnAngleConstraintArrayDeserializer.deserialize(jsonParser, networkActionAdder);
break;
case ON_VOLTAGE_CONSTRAINT_USAGE_RULES:
jsonParser.nextToken();
OnVoltageConstraintArrayDeserializer.deserialize(jsonParser, networkActionAdder);
break;
case ON_FLOW_CONSTRAINT_IN_COUNTRY_USAGE_RULES:
jsonParser.nextToken();
OnFlowConstraintInCountryArrayDeserializer.deserialize(jsonParser, networkActionAdder);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
/*
* Copyright (c) 2023, 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.farao_community.farao.data.crac_io_json.deserializers;

import com.farao_community.farao.commons.FaraoException;
import com.farao_community.farao.data.crac_api.RemedialActionAdder;
import com.farao_community.farao.data.crac_api.usage_rule.OnVoltageConstraintAdder;
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonToken;

import java.io.IOException;

import static com.farao_community.farao.data.crac_io_json.JsonSerializationConstants.*;

/**
* @author Fabrice Buscaylet {@literal <fabrice.buscaylet at artelys.com>}
*/
public final class OnVoltageConstraintArrayDeserializer {
private OnVoltageConstraintArrayDeserializer() {
}

public static void deserialize(JsonParser jsonParser, RemedialActionAdder<?> ownerAdder) throws IOException {
while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
OnVoltageConstraintAdder<?> adder = ownerAdder.newOnVoltageConstraintUsageRule();
while (!jsonParser.nextToken().isStructEnd()) {
switch (jsonParser.getCurrentName()) {
case INSTANT:
adder.withInstant(deserializeInstant(jsonParser.nextTextValue()));
break;
case VOLTAGE_CNEC_ID:
adder.withVoltageCnec(jsonParser.nextTextValue());
break;
default:
throw new FaraoException("Unexpected field in OnVoltageConstraint: " + jsonParser.getCurrentName());
}
}
adder.add();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,10 @@ public static void deserialize(JsonParser jsonParser, DeserializationContext des
jsonParser.nextToken();
OnAngleConstraintArrayDeserializer.deserialize(jsonParser, pstRangeActionAdder);
break;
case ON_VOLTAGE_CONSTRAINT_USAGE_RULES:
jsonParser.nextToken();
OnVoltageConstraintArrayDeserializer.deserialize(jsonParser, pstRangeActionAdder);
break;
case ON_FLOW_CONSTRAINT_IN_COUNTRY_USAGE_RULES:
jsonParser.nextToken();
OnFlowConstraintInCountryArrayDeserializer.deserialize(jsonParser, pstRangeActionAdder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,10 @@
import com.farao_community.farao.data.crac_api.cnec.VoltageCnec;
import com.farao_community.farao.data.crac_api.network_action.*;
import com.farao_community.farao.data.crac_api.range.StandardRange;
import com.farao_community.farao.data.crac_api.range.TapRange;
import com.farao_community.farao.data.crac_api.range_action.HvdcRangeAction;
import com.farao_community.farao.data.crac_api.range_action.InjectionRangeAction;
import com.farao_community.farao.data.crac_api.range_action.PstRangeAction;
import com.farao_community.farao.data.crac_api.range.TapRange;
import com.farao_community.farao.data.crac_api.threshold.BranchThreshold;
import com.farao_community.farao.data.crac_api.threshold.Threshold;
import com.farao_community.farao.data.crac_api.usage_rule.*;
Expand All @@ -43,6 +43,7 @@ public CracJsonSerializerModule() {
this.addSerializer(OnContingencyState.class, new OnStateSerializer());
this.addSerializer(OnFlowConstraint.class, new OnFlowConstraintSerializer());
this.addSerializer(OnAngleConstraint.class, new OnAngleConstraintSerializer());
this.addSerializer(OnVoltageConstraint.class, new OnVoltageConstraintSerializer());
this.addSerializer(OnFlowConstraintInCountry.class, new OnFlowConstraintInCountrySerializer());
this.addSerializer(TapRange.class, new TapRangeSerializer());
this.addSerializer(StandardRange.class, new StandardRangeSerializer());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/*
* Copyright (c) 2023, 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.farao_community.farao.data.crac_io_json.serializers;

import com.farao_community.farao.data.crac_api.usage_rule.OnVoltageConstraint;
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;

import java.io.IOException;

import static com.farao_community.farao.data.crac_io_json.JsonSerializationConstants.*;

/**
* @author Fabrice Buscaylet {@literal <fabrice.buscaylet at artelys.com>}
*/
public class OnVoltageConstraintSerializer extends AbstractJsonSerializer<OnVoltageConstraint> {
@Override
public void serialize(OnVoltageConstraint value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
gen.writeStartObject();
gen.writeStringField(INSTANT, serializeInstant(value.getInstant()));
gen.writeStringField(VOLTAGE_CNEC_ID, value.getVoltageCnec().getId());
gen.writeEndObject();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public static void serializeUsageRules(RemedialAction<?> remedialAction, JsonGen
serializeUsageRules(remedialAction, OnContingencyState.class, ON_CONTINGENCY_STATE_USAGE_RULES, gen);
serializeUsageRules(remedialAction, OnFlowConstraint.class, ON_FLOW_CONSTRAINT_USAGE_RULES, gen);
serializeUsageRules(remedialAction, OnAngleConstraint.class, ON_ANGLE_CONSTRAINT_USAGE_RULES, gen);
serializeUsageRules(remedialAction, OnVoltageConstraint.class, ON_VOLTAGE_CONSTRAINT_USAGE_RULES, gen);
serializeUsageRules(remedialAction, OnFlowConstraintInCountry.class, ON_FLOW_CONSTRAINT_IN_COUNTRY_USAGE_RULES, gen);
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ void roundTripTest() {
assertEquals(7, importedCrac.getFlowCnecs().size());
assertEquals(1, importedCrac.getAngleCnecs().size());
assertEquals(1, importedCrac.getVoltageCnecs().size());
assertEquals(6, importedCrac.getRangeActions().size());
assertEquals(7, importedCrac.getRangeActions().size());
assertEquals(4, importedCrac.getNetworkActions().size());

// --------------------------
Expand Down Expand Up @@ -274,6 +274,15 @@ void roundTripTest() {
assertEquals(CURATIVE, onAngleConstraint.getInstant());
assertSame(crac.getCnec("angleCnecId"), onAngleConstraint.getAngleCnec());

// check OnVoltageConstraint usage rule
List<UsageRule> pstRange4IdUsageRules = crac.getPstRangeAction("pstRange4Id").getUsageRules();
assertEquals(1, pstRange4IdUsageRules.size());
UsageRule pstRange4IdFirstUsageRules = pstRange4IdUsageRules.get(0);
assertTrue(pstRange4IdFirstUsageRules instanceof OnVoltageConstraint);
OnVoltageConstraint onVoltageConstraint = (OnVoltageConstraint) pstRange4IdFirstUsageRules;
assertEquals(CURATIVE, onVoltageConstraint.getInstant());
assertSame(crac.getCnec("voltageCnecId"), onVoltageConstraint.getVoltageCnec());

// -----------------------------
// --- test HvdcRangeActions ---
// -----------------------------
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,11 @@
import java.io.InputStream;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.farao_community.farao.data.crac_api.Instant.*;
import static com.farao_community.farao.data.crac_api.usage_rule.UsageMethod.AVAILABLE;
import static com.farao_community.farao.data.crac_api.usage_rule.UsageMethod.FORCED;
import static org.junit.jupiter.api.Assertions.*;
import static org.junit.jupiter.api.Assertions.assertTrue;

/**
* @author Baptiste Seguinot {@literal <baptiste.seguinot at rte-france.com>}
Expand Down Expand Up @@ -186,6 +184,27 @@ void importV1Point6Test() {
testContentOfV1Point6Crac(crac);
}

@Test
void importV1Point7Test() {

// renaming usage rules
// Branch threshold rule no longer handled

InputStream cracFile = getClass().getResourceAsStream("/retrocompatibility/v1/crac-v1.7.json");

Crac crac = new JsonImport().importCrac(cracFile);

assertEquals(2, crac.getContingencies().size());
assertEquals(7, crac.getFlowCnecs().size());
assertEquals(1, crac.getAngleCnecs().size());
assertEquals(1, crac.getVoltageCnecs().size());
assertEquals(4, crac.getNetworkActions().size());
assertEquals(4, crac.getPstRangeActions().size());
assertEquals(2, crac.getHvdcRangeActions().size());
assertEquals(1, crac.getInjectionRangeActions().size());
testContentOfV1Point7Crac(crac);
}

private void testContentOfV1Point0Crac(Crac crac) {

// --------------------------
Expand Down Expand Up @@ -378,7 +397,7 @@ private void testContentOfV1Point0Crac(Crac crac) {
assertEquals(Unit.MEGAWATT, hvdcRange.getUnit());

// check usage rules
assertEquals(4, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnInstant.class::isInstance).collect(Collectors.toList()).size());
assertEquals(4, (int) crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnInstant.class::isInstance).count());
}

void testContentOfV1Point1Crac(Crac crac) {
Expand Down Expand Up @@ -416,8 +435,8 @@ void testContentOfV1Point2Crac(Crac crac) {
assertEquals(2, crac.getInjectionRangeAction("injectionRange1Id").getRanges().size());

// check usage rules
assertEquals(3, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnContingencyState.class::isInstance).collect(Collectors.toList()).size());
assertEquals(3, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnFlowConstraint.class::isInstance).collect(Collectors.toList()).size());
assertEquals(3, (int) crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnContingencyState.class::isInstance).count());
assertEquals(3, (int) crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnFlowConstraint.class::isInstance).count());
}

void testContentOfV1Point3Crac(Crac crac) {
Expand Down Expand Up @@ -459,7 +478,7 @@ void testContentOfV1Point4Crac(Crac crac) {
assertEquals(CURATIVE, onAngleConstraint.getInstant());

// check usage rules
assertEquals(1, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnAngleConstraint.class::isInstance).collect(Collectors.toList()).size());
assertEquals(1, (int) crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnAngleConstraint.class::isInstance).count());
}

void testContentOfV1Point5Crac(Crac crac) {
Expand Down Expand Up @@ -487,15 +506,21 @@ void testContentOfV1Point6Crac(Crac crac) {

testContentOfV1Point5Crac(crac);
// test usage rules
assertEquals(4, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnInstant.class::isInstance).collect(Collectors.toList()).size());
assertEquals(3, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnContingencyState.class::isInstance).collect(Collectors.toList()).size());
assertEquals(3, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnFlowConstraint.class::isInstance).collect(Collectors.toList()).size());
assertEquals(1, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnAngleConstraint.class::isInstance).collect(Collectors.toList()).size());
assertEquals(4, (int) crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnInstant.class::isInstance).count());
assertEquals(3, (int) crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnContingencyState.class::isInstance).count());
assertEquals(3, (int) crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnFlowConstraint.class::isInstance).count());
assertEquals(1, (int) crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnAngleConstraint.class::isInstance).count());
// test speed
assertEquals(10, crac.getPstRangeAction("pstRange1Id").getSpeed().get().intValue());
assertEquals(20, crac.getHvdcRangeAction("hvdcRange1Id").getSpeed().get().intValue());
assertEquals(30, crac.getInjectionRangeAction("injectionRange1Id").getSpeed().get().intValue());
assertEquals(40, crac.getNetworkAction("complexNetworkActionId").getSpeed().get().intValue());
}

void testContentOfV1Point7Crac(Crac crac) {

testContentOfV1Point6Crac(crac);
// test new voltage constraint usage rules
assertEquals(1, crac.getRemedialActions().stream().map(RemedialAction::getUsageRules).flatMap(List::stream).filter(OnVoltageConstraint.class::isInstance).count());
}
}
Loading

0 comments on commit d2d0e70

Please sign in to comment.