Skip to content

Commit

Permalink
SecurityAnalysis API: Add Hvdc action (#2454)
Browse files Browse the repository at this point in the history
Signed-off-by: Etienne LESOT <etienne.lesot@rte-france.com>
Co-authored-by: Anne Tilloy <anne.tilloy@rte-france.com>
Co-authored-by: Damien Jeandemange <damien.jeandemange@artelys.com>
  • Loading branch information
3 people authored and anistouri committed Mar 13, 2023
1 parent 7f5c637 commit 8e6bdb4
Show file tree
Hide file tree
Showing 11 changed files with 390 additions and 17 deletions.
6 changes: 6 additions & 0 deletions commons/src/main/java/com/powsybl/commons/json/JsonUtil.java
Original file line number Diff line number Diff line change
Expand Up @@ -631,4 +631,10 @@ public static void writeOptionalDouble(JsonGenerator jsonGenerator, String field
jsonGenerator.writeNumberField(field, optional.getAsDouble());
}
}

public static void writeOptionalBoolean(JsonGenerator jsonGenerator, String field, Optional<Boolean> optional) throws IOException {
if (optional.isPresent()) {
jsonGenerator.writeBooleanField(field, optional.get());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

import java.util.Objects;
import java.util.Optional;
import java.util.OptionalDouble;

/**
* An action to:
Expand Down Expand Up @@ -65,20 +66,19 @@ public Optional<Boolean> isActivePowerRelativeValue() {
return Optional.ofNullable(activePowerRelativeValue);
}

public Optional<Double> getActivePowerValue() {
return Optional.ofNullable(activePowerValue);
public OptionalDouble getActivePowerValue() {
return activePowerValue == null ? OptionalDouble.empty() : OptionalDouble.of(activePowerValue);
}

public Optional<Boolean> isVoltageRegulatorOn() {
return Optional.ofNullable(voltageRegulatorOn);
}

public Optional<Double> getTargetV() {
return Optional.ofNullable(targetV);
public OptionalDouble getTargetV() {
return targetV == null ? OptionalDouble.empty() : OptionalDouble.of(targetV);
}

public Optional<Double> getTargetQ() {
return Optional.ofNullable(targetQ);
public OptionalDouble getTargetQ() {
return targetQ == null ? OptionalDouble.empty() : OptionalDouble.of(targetQ);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
/**
* 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.security.action;

import com.powsybl.iidm.network.HvdcLine;

import java.util.Objects;
import java.util.Optional;
import java.util.OptionalDouble;

/**
* An action to modify HVDC parameters and/or operating mode.
* <ul>
* <li>{@code acEmulationEnabled} parameter set to true correspond to AC emulation operation,
* false to fixed active power setpoint.
* <li>Note that AC emulation is relevant only for VSC converter station.
* <li>{@code droop} and {@code p0} parameters are used for AC emulation only.<br>
* <li>{@code activePowerSetpoint} and {@code converterMode} parameters are for fixed
* active power setpoint operation only. The {@code relativeValue} attribute should be used only
* when defining fixed active power setpoint.
* </ul>
*
* @author Etienne Lesot <etienne.lesot@rte-france.com>
*/
public class HvdcAction extends AbstractAction {

public static final String NAME = "HVDC";

private final String hvdcId;
private final Boolean acEmulationEnabled;
private final Double activePowerSetpoint;
private final HvdcLine.ConvertersMode converterMode;
private final Double droop;
private final Double p0;
private final Boolean relativeValue;

HvdcAction(String id, String hvdcId, Boolean acEmulationEnabled, Double activePowerSetpoint, HvdcLine.ConvertersMode converterMode, Double droop, Double p0, Boolean relativeValue) {
super(id);
this.hvdcId = Objects.requireNonNull(hvdcId);
this.acEmulationEnabled = acEmulationEnabled;
this.activePowerSetpoint = activePowerSetpoint;
this.converterMode = converterMode;
this.droop = droop;
this.p0 = p0;
this.relativeValue = relativeValue;
}

@Override
public String getType() {
return NAME;
}

public String getHvdcId() {
return hvdcId;
}

public Optional<HvdcLine.ConvertersMode> getConverterMode() {
return Optional.ofNullable(converterMode);
}

public OptionalDouble getDroop() {
return droop == null ? OptionalDouble.empty() : OptionalDouble.of(droop);
}

public OptionalDouble getActivePowerSetpoint() {
return activePowerSetpoint == null ? OptionalDouble.empty() : OptionalDouble.of(activePowerSetpoint);
}

public OptionalDouble getP0() {
return p0 == null ? OptionalDouble.empty() : OptionalDouble.of(p0);
}

public Optional<Boolean> isAcEmulationEnabled() {
return Optional.ofNullable(acEmulationEnabled);
}

public Optional<Boolean> isRelativeValue() {
return Optional.ofNullable(relativeValue);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/**
* 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.security.action;

import com.powsybl.iidm.network.HvdcLine;

/**
*
* @author Etienne Lesot <etienne.lesot@rte-france.com>
*/
public class HvdcActionBuilder {

private String id;
private String hvdcId;
private Boolean acEmulationEnabled;
private Double activePowerSetpoint = null;
private HvdcLine.ConvertersMode converterMode = null;
private Double droop = null;
private Double p0 = null;
private Boolean relativeValue = null;

public HvdcAction build() {
return new HvdcAction(id, hvdcId, acEmulationEnabled, activePowerSetpoint, converterMode, droop, p0, relativeValue);
}

public HvdcActionBuilder withId(String id) {
this.id = id;
return this;
}

public HvdcActionBuilder withHvdcId(String hvdcId) {
this.hvdcId = hvdcId;
return this;
}

public HvdcActionBuilder withAcEmulationEnabled(Boolean acEmulationEnabled) {
this.acEmulationEnabled = acEmulationEnabled;
return this;
}

public HvdcActionBuilder withActivePowerSetpoint(Double activePowerSetpoint) {
this.activePowerSetpoint = activePowerSetpoint;
return this;
}

public HvdcActionBuilder withDroop(Double droop) {
this.droop = droop;
return this;
}

public HvdcActionBuilder withP0(Double p0) {
this.p0 = p0;
return this;
}

public HvdcActionBuilder withRelativeValue(Boolean relativeValue) {
this.relativeValue = relativeValue;
return this;
}

public HvdcActionBuilder withConverterMode(HvdcLine.ConvertersMode converterMode) {
this.converterMode = converterMode;
return this;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
package com.powsybl.security.action;

import java.util.Objects;
import java.util.Optional;
import java.util.OptionalDouble;

/**
* An action to:
Expand Down Expand Up @@ -55,12 +55,11 @@ public boolean isRelativeValue() {
return relativeValue;
}

public Optional<Double> getActivePowerValue() {
return Optional.ofNullable(activePowerValue);
public OptionalDouble getActivePowerValue() {
return activePowerValue == null ? OptionalDouble.empty() : OptionalDouble.of(activePowerValue);
}

public Optional<Double> getReactivePowerValue() {
return Optional.ofNullable(reactivePowerValue);
public OptionalDouble getReactivePowerValue() {
return reactivePowerValue == null ? OptionalDouble.empty() : OptionalDouble.of(reactivePowerValue);
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,9 @@ private void configureActionsSerialization() {
new PhaseTapChangerRegulationActionSerializer(), new PhaseTapChangerRegulationActionDeserializer());
registerActionType(RatioTapChangerRegulationAction.class, RatioTapChangerRegulationAction.NAME,
new RatioTapChangerRegulationActionSerializer(), new RatioTapChangerRegulationActionDeserializer());
registerActionType(GeneratorAction.class, GeneratorAction.NAME,
new GeneratorActionSerializer(), new GeneratorActionDeserializer());
registerActionType(LoadAction.class, LoadAction.NAME,
new LoadActionSerializer(), new LoadActionDeserializer());
registerActionType(GeneratorAction.class, GeneratorAction.NAME, new GeneratorActionSerializer(), new GeneratorActionDeserializer());
registerActionType(LoadAction.class, LoadAction.NAME, new LoadActionSerializer(), new LoadActionDeserializer());
registerActionType(HvdcAction.class, HvdcAction.NAME, new HvdcActionSerializer(), new HvdcActionDeserializer());
}

private <T> void registerActionType(Class<T> actionClass, String typeName, JsonSerializer<T> serializer, JsonDeserializer<T> deserializer) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
/**
* 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.security.json.action;

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;
import com.powsybl.commons.json.JsonUtil;
import com.powsybl.iidm.network.HvdcLine;
import com.powsybl.security.action.HvdcAction;
import com.powsybl.security.action.HvdcActionBuilder;

import java.io.IOException;

/**
* @author Etienne Lesot <etienne.lesot@rte-france.com>
*/
public class HvdcActionDeserializer extends StdDeserializer<HvdcAction> {

public HvdcActionDeserializer() {
super(HvdcAction.class);
}

private static class ParsingContext {
String id;
String hvdcId;
Boolean acEmulationEnabled;
Double activePowerSetpoint;
HvdcLine.ConvertersMode converterMode;
Double droop;
Double p0;
Boolean relativeValue;
}

@Override
public HvdcAction deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
ParsingContext context = new ParsingContext();
JsonUtil.parsePolymorphicObject(jsonParser, name -> {
switch (name) {
case "type":
if (!HvdcAction.NAME.equals(jsonParser.nextTextValue())) {
throw JsonMappingException.from(jsonParser, "Expected type " + HvdcAction.NAME);
}
return true;
case "id":
context.id = jsonParser.nextTextValue();
return true;
case "hvdcId":
context.hvdcId = jsonParser.nextTextValue();
return true;
case "acEmulationEnabled":
jsonParser.nextToken();
context.acEmulationEnabled = jsonParser.getValueAsBoolean();
return true;
case "activePowerSetpoint":
jsonParser.nextToken();
context.activePowerSetpoint = jsonParser.getValueAsDouble();
return true;
case "converterMode":
context.converterMode = HvdcLine.ConvertersMode.valueOf(jsonParser.nextTextValue());
return true;
case "droop":
jsonParser.nextToken();
context.droop = jsonParser.getValueAsDouble();
return true;
case "p0":
jsonParser.nextToken();
context.p0 = jsonParser.getValueAsDouble();
return true;
case "relativeValue":
jsonParser.nextToken();
context.relativeValue = jsonParser.getValueAsBoolean();
return true;
default:
return false;
}
});
return new HvdcActionBuilder()
.withId(context.id)
.withHvdcId(context.hvdcId)
.withAcEmulationEnabled(context.acEmulationEnabled)
.withActivePowerSetpoint(context.activePowerSetpoint)
.withConverterMode(context.converterMode)
.withDroop(context.droop)
.withP0(context.p0)
.withRelativeValue(context.relativeValue)
.build();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/**
* 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/.
* SPDX-License-Identifier: MPL-2.0
*/
package com.powsybl.security.json.action;

import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;
import com.powsybl.commons.json.JsonUtil;
import com.powsybl.security.action.HvdcAction;

import java.io.IOException;

/**
* @author Etienne Lesot <etienne.lesot@rte-france.com>
*/
public class HvdcActionSerializer extends StdSerializer<HvdcAction> {
public HvdcActionSerializer() {
super(HvdcAction.class);
}

@Override
public void serialize(HvdcAction action, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
jsonGenerator.writeStartObject();
jsonGenerator.writeStringField("type", action.getType());
jsonGenerator.writeStringField("id", action.getId());
jsonGenerator.writeStringField("hvdcId", action.getHvdcId());
JsonUtil.writeOptionalBoolean(jsonGenerator, "acEmulationEnabled", action.isAcEmulationEnabled());
JsonUtil.writeOptionalDouble(jsonGenerator, "activePowerSetpoint", action.getActivePowerSetpoint());
JsonUtil.writeOptionalEnum(jsonGenerator, "converterMode", action.getConverterMode());
JsonUtil.writeOptionalDouble(jsonGenerator, "droop", action.getDroop());
JsonUtil.writeOptionalDouble(jsonGenerator, "p0", action.getP0());
JsonUtil.writeOptionalBoolean(jsonGenerator, "relativeValue", action.isRelativeValue());
jsonGenerator.writeEndObject();
}
}
Loading

0 comments on commit 8e6bdb4

Please sign in to comment.