JsonActionTest.java
package com.powsybl.action.json;
import com.powsybl.action.*;
import com.powsybl.commons.test.AbstractSerDeTest;
import com.powsybl.commons.test.ComparisonUtils;
import com.powsybl.iidm.network.PhaseTapChanger;
import com.powsybl.iidm.network.StaticVarCompensator;
import com.powsybl.iidm.network.ThreeSides;
import com.powsybl.iidm.network.identifiers.IdBasedNetworkElementIdentifier;
import com.powsybl.iidm.network.identifiers.NetworkElementIdentifier;
import com.powsybl.iidm.network.identifiers.VoltageLevelAndOrderNetworkElementIdentifier;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.ValueSource;
import java.io.*;
import java.util.*;
import static com.powsybl.action.PercentChangeLoadAction.QModificationStrategy.CONSTANT_Q;
import static com.powsybl.iidm.network.HvdcLine.ConvertersMode.SIDE_1_RECTIFIER_SIDE_2_INVERTER;
import static org.junit.jupiter.api.Assertions.*;
public class JsonActionTest extends AbstractSerDeTest {
@Test
void actionRoundTrip() throws IOException {
List<Action> actions = new ArrayList<>();
actions.add(new SwitchAction("id1", "switchId1", true));
actions.add(new MultipleActionsAction("id2", Collections.singletonList(new SwitchAction("id3", "switchId2", true))));
actions.add(new TerminalsConnectionAction("id3", "lineId3", true)); // both sides.
actions.add(new TerminalsConnectionAction("id4", "lineId4", false)); // both sides.
actions.add(new PhaseTapChangerTapPositionAction("id5", "transformerId1", true, 5, ThreeSides.TWO));
actions.add(new PhaseTapChangerTapPositionAction("id6", "transformerId2", false, 12));
actions.add(new PhaseTapChangerTapPositionAction("id7", "transformerId3", true, -5, ThreeSides.ONE));
actions.add(new PhaseTapChangerTapPositionAction("id8", "transformerId3", false, 2, ThreeSides.THREE));
actions.add(new GeneratorActionBuilder().withId("id9").withGeneratorId("generatorId1").withActivePowerRelativeValue(true).withActivePowerValue(100.0).build());
actions.add(new GeneratorActionBuilder().withId("id10").withGeneratorId("generatorId2").withVoltageRegulatorOn(true).withTargetV(225.0).build());
actions.add(new GeneratorActionBuilder().withId("id11").withGeneratorId("generatorId2").withVoltageRegulatorOn(false).withTargetQ(400.0).build());
actions.add(new LoadActionBuilder().withId("id12").withLoadId("loadId1").withRelativeValue(false).withActivePowerValue(50.0).build());
actions.add(new LoadActionBuilder().withId("id13").withLoadId("loadId1").withRelativeValue(true).withReactivePowerValue(5.0).build());
actions.add(new PercentChangeLoadActionBuilder().withId("id26").withLoadId("loadId1").withP0PercentChange(5.0).withQModificationStrategy(CONSTANT_Q).build());
actions.add(new DanglingLineActionBuilder().withId("id17").withDanglingLineId("dlId1").withRelativeValue(true).withReactivePowerValue(5.0).build());
actions.add(new RatioTapChangerTapPositionAction("id14", "transformerId4", false, 2, ThreeSides.THREE));
actions.add(new RatioTapChangerTapPositionAction("id15", "transformerId5", true, 1));
actions.add(RatioTapChangerRegulationAction.activateRegulation("id16", "transformerId5", ThreeSides.THREE));
actions.add(PhaseTapChangerRegulationAction.activateAndChangeRegulationMode("id17", "transformerId5", ThreeSides.ONE,
PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL, 10.0));
actions.add(PhaseTapChangerRegulationAction.deactivateRegulation("id18",
"transformerId6", ThreeSides.ONE));
actions.add(PhaseTapChangerRegulationAction.activateAndChangeRegulationMode("id19",
"transformerId6", ThreeSides.ONE,
PhaseTapChanger.RegulationMode.ACTIVE_POWER_CONTROL, 15.0));
actions.add(RatioTapChangerRegulationAction.activateRegulationAndChangeTargetV("id20", "transformerId5", 90.0));
actions.add(RatioTapChangerRegulationAction.deactivateRegulation("id21", "transformerId5", ThreeSides.THREE));
actions.add(new HvdcActionBuilder()
.withId("id22")
.withHvdcId("hvdc1")
.withAcEmulationEnabled(false)
.build());
actions.add(new HvdcActionBuilder()
.withId("id23")
.withHvdcId("hvdc2")
.withAcEmulationEnabled(true)
.build());
actions.add(new HvdcActionBuilder()
.withId("id24")
.withHvdcId("hvdc2")
.withAcEmulationEnabled(true)
.withDroop(121.0)
.withP0(42.0)
.withConverterMode(SIDE_1_RECTIFIER_SIDE_2_INVERTER)
.withRelativeValue(false)
.build());
actions.add(new HvdcActionBuilder()
.withId("id25")
.withHvdcId("hvdc1")
.withAcEmulationEnabled(false)
.withActivePowerSetpoint(12.0)
.withRelativeValue(true)
.build());
actions.add(new ShuntCompensatorPositionActionBuilder().withId("id22").withShuntCompensatorId("shuntId1").withSectionCount(5).build());
actions.add(new StaticVarCompensatorActionBuilder().withId("id23")
.withStaticVarCompensatorId("svc").withRegulationMode(StaticVarCompensator.RegulationMode.VOLTAGE)
.withVoltageSetpoint(56.0).build());
actions.add(new StaticVarCompensatorActionBuilder().withId("id24")
.withStaticVarCompensatorId("svc").withRegulationMode(StaticVarCompensator.RegulationMode.REACTIVE_POWER)
.withReactivePowerSetpoint(120.0).build());
actions.add(new TerminalsConnectionAction("id4", "transformerId25", ThreeSides.THREE, true)); // only one side.
actions.add(new AreaInterchangeTargetAction("id99", "AreaA", 101.0));
actions.add(new AreaInterchangeTargetAction("idDisabledTarget", "AreaA", Double.NaN));
ActionList actionList = new ActionList(actions);
roundTripTest(actionList, ActionList::writeJsonFile, ActionList::readJsonFile, "/ActionFileTest.json");
}
@ParameterizedTest
@ValueSource(strings = {"/ActionFileTestV1.0.json", "/ActionFileTestV1.1.json"})
void actionsReadOldVersion(String path) {
ActionList actionList = ActionList.readJsonInputStream(getClass().getResourceAsStream(path));
try (ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
actionList.writeJsonOutputStream(bos);
ComparisonUtils.assertTxtEquals(getClass().getResourceAsStream("/ActionFileTest.json"), new ByteArrayInputStream(bos.toByteArray()));
} catch (Exception e) {
// Should not happen
fail();
}
}
@Test
void wrongActions() throws IOException {
try (final InputStream inputStream = getClass().getResourceAsStream("/WrongActionFileTest.json")) {
assertEquals("com.fasterxml.jackson.databind.JsonMappingException: for phase tap changer tap position action relative value field can't be null\n" +
" at [Source: REDACTED (`StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION` disabled); line: 8, column: 3] (through reference chain: java.util.ArrayList[0])", assertThrows(UncheckedIOException.class, () ->
ActionList.readJsonInputStream(inputStream)).getMessage());
}
try (final InputStream inputStream3 = getClass().getResourceAsStream("/ActionFileTestWrongVersion.json")) {
assertTrue(assertThrows(UncheckedIOException.class, () -> ActionList
.readJsonInputStream(inputStream3))
.getMessage()
.contains("actions. Tag: value is not valid for version 1.1. Version should be <= 1.0"));
}
}
@Test
void identifierActionList() throws IOException {
Map<ActionBuilder, NetworkElementIdentifier> elementIdentifierMap = new HashMap<>();
elementIdentifierMap.put(new TerminalsConnectionActionBuilder().withId("lineConnectionActionId").withOpen(true).withSide(ThreeSides.ONE),
new VoltageLevelAndOrderNetworkElementIdentifier("VLHV1", "VLHV2", '1'));
elementIdentifierMap.put(new SwitchActionBuilder().withId("switchActionId").withOpen(true),
new IdBasedNetworkElementIdentifier("switch 1 id"));
IdentifierActionList identifierActionList = new IdentifierActionList(Collections.emptyList(), elementIdentifierMap);
roundTripTest(identifierActionList, ActionList::writeJsonFile, ActionList::readJsonFile, "/IdentifierActionListTest.json");
}
}