Skip to content

Commit

Permalink
Merge 804e2cb into b2b8b80
Browse files Browse the repository at this point in the history
  • Loading branch information
CBiasuzzi committed Jan 23, 2019
2 parents b2b8b80 + 804e2cb commit 0314540
Show file tree
Hide file tree
Showing 8 changed files with 408 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,192 @@
/**
* Copyright (c) 2018, 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 eu.itesla_project.iidm.ddb.eurostag_imp_exp;

import com.powsybl.commons.jaxb.JaxbUtil;
import com.powsybl.iidm.network.Branch;
import com.powsybl.iidm.network.Network;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Path;
import java.text.ParseException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
* @author Christian Biasuzzi <christian.biasuzzi@techrain.it>
*/
public final class AutomatonA56 {
/*
A56 Automata (Loss of Synchronism Protection)
<lossOfSynchronismProtections>
<lossOfSynchronismProtection>
<branch>IIDMID</branch>
<side>2</side>
<beat>2</beat>
<delay>0.5</delay>
<voltageDip>0.7</voltageDip>
<baseVoltage>300.0</baseVoltage>
<timeConstant>10.0</timeConstant>
<comment>MM</comment>
</lossOfSynchronismProtection>
</lossOfSynchronismProtections>
*/

static Logger LOGGER = LoggerFactory.getLogger(AutomatonA56.class);

public static final String A56_AUTOMATA_ID = "A56";

@XmlRootElement(name = "lossOfSynchronismProtection")
@XmlAccessorType(XmlAccessType.FIELD)
private static class LossOfSynchronismProtection {
private String branch; //Eurostag branch identifier (1stnode 2ndnode orderCode)
private String side; //indicates which bus should be put first in the dta record
private int beat; //number of beats before activation
private Double delay; //delay before action (breaker opening, in s)
private Double voltageDip; //initial voltage proportion (in pu)
private Double baseVoltage; //base voltage (in kV)
private Double timeConstant; //time constant for the measurement of the reference voltage (in s)
private String comment; //two letters indicating the indices of the zons that are disconnected by the protection

public LossOfSynchronismProtection() {
}

public LossOfSynchronismProtection(String branch, String side, int beat, Double delay, Double voltageDip, Double baseVoltage, Double timeConstant, String comment) {
this.branch = branch;
this.side = side;
this.beat = beat;
this.delay = delay;
this.voltageDip = voltageDip;
this.baseVoltage = baseVoltage;
this.timeConstant = timeConstant;
this.comment = comment;
}

@Override
public String toString() {
return "LossOfSynchronismProtection{" +
"branch='" + branch + '\'' +
", side=" + side +
", beat=" + beat +
", delay=" + delay +
", voltageDip=" + voltageDip +
", baseVoltage=" + baseVoltage +
", timeConstant=" + timeConstant +
", comment='" + comment + '\'' +
'}';
}
}

@XmlRootElement(name = "lossOfSynchronismProtections")
@XmlAccessorType(XmlAccessType.FIELD)
private static class LossOfSynchronismProtections {
@XmlElement(name = "lossOfSynchronismProtection")
List<LossOfSynchronismProtection> lossOfSynchronismProtections;

public List<LossOfSynchronismProtection> getLossOfSynchronismProtections() {
return lossOfSynchronismProtections;
}

public void setLossOfSynchronismProtections(List<LossOfSynchronismProtection> lossOfSynchronismProtections) {
this.lossOfSynchronismProtections = lossOfSynchronismProtections;
}

@Override
public String toString() {
return "lossOfSynchronismProtections=" + lossOfSynchronismProtections;
}
}

private AutomatonA56() {
}

public static EurostagRecord createA56Record(LossOfSynchronismProtection loss, String eurostagBranchId) {
Objects.requireNonNull(loss);
Objects.requireNonNull(eurostagBranchId);
HashMap<String, Object> zm = new HashMap<String, Object>();
zm.put("BRANCH_ID", eurostagBranchId);
zm.put("NO_BEATS", loss.beat);
zm.put("DELAY", loss.delay);
zm.put("INITIAL_VOLTAGE", loss.voltageDip);
zm.put("BASE_VOLTAGE", loss.baseVoltage);
zm.put("TIME_CONSTANT", loss.timeConstant);
zm.put("COMMENTS", loss.comment);
EurostagRecord eRecord = new EurostagRecord(A56_AUTOMATA_ID, zm);
return eRecord;
}

public static void writeToDta(Network network, PrintStream out, Map<String, String> iidm2eurostagId, Path defaultAutomatonA56DetailsFile) throws IOException, ParseException {
Objects.requireNonNull(iidm2eurostagId);
LossOfSynchronismProtections losses = JaxbUtil.unmarchallFile(LossOfSynchronismProtections.class, defaultAutomatonA56DetailsFile);
DtaParser.dumpAutomatonHeader(A56_AUTOMATA_ID, false, out);
losses.getLossOfSynchronismProtections().forEach(loss -> {
Branch branch = network.getBranch(loss.branch);
String eurostagId = iidm2eurostagId.get(loss.branch);
if (eurostagId == null) {
LOGGER.warn("skipping entry for iidm id {}: eurostag id not found in mapping.", loss.branch);
} else {
if (eurostagId.length() != 19) {
LOGGER.warn("skipping entry for iidm id {}: unexpected format for eurostag id in mapping.", loss.branch);
} else {
// eurostag's branch id format expected: xxxxxxxx xxxxxxxx x
String side1 = eurostagId.substring(0, 8);
String side2 = eurostagId.substring(9, 17);
String parallelIndex = eurostagId.substring(18);
String aBranch = loss.branch;

switch (loss.side) {
case "1":
aBranch = side1 + " " + side2 + " " + parallelIndex;
break;
case "2":
aBranch = side2 + " " + side1 + " " + parallelIndex;
break;
case "":
// side1 is the bus whose base voltage is equal to the protection's base voltage
// else (2 buses of the same voltage or no bus of the indicated voltage, print a warning and put it on side 1
double baseVoltage1 = branch.getTerminal1().getVoltageLevel().getNominalV();
double baseVoltage2 = branch.getTerminal2().getVoltageLevel().getNominalV();
if (Double.compare(baseVoltage1, baseVoltage2) != 0) {
if (Double.compare(loss.baseVoltage, baseVoltage1) == 0) {
aBranch = side1 + " " + side2 + " " + parallelIndex;
} else if (Double.compare(loss.baseVoltage, baseVoltage2) == 0) {
aBranch = side2 + " " + side1 + " " + parallelIndex;
} else {
LOGGER.warn("{}; branch bus1 {} (base voltage1 {}) - bus2 {} (base voltage2 {}). Using bus1 {} ", loss, side1, baseVoltage1, side2, baseVoltage2, side1);
aBranch = side1 + " " + side2 + " " + parallelIndex;
}
} else {
LOGGER.warn("{}; branch bus1 {} and bus2 {} have the same base voltage {}. Using bus1 {} ", loss, side1, side2, baseVoltage1, side1);
aBranch = side1 + " " + side2 + " " + parallelIndex;
}
break;
default:
LOGGER.warn("skipping entry for iidm id {}: unexpected 'side' value {}.", loss.branch, loss.side);
}
LOGGER.debug("{}; eurostag branch id: {}", loss, aBranch);
try {
DtaParser.dumpZone(createA56Record(loss, aBranch), out);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
});
DtaParser.dumpAutomatonHeader(A56_AUTOMATA_ID, true, out);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@
import com.powsybl.commons.config.ModuleConfig;
import com.powsybl.commons.config.PlatformConfig;

import java.nio.file.Path;

/**
*
* @author Geoffroy Jamgotchian <geoffroy.jamgotchian at rte-france.com>
Expand Down Expand Up @@ -38,11 +40,16 @@ public class DdExportConfig {
private static final double DEFAULT_AUTOMATON_A17_MINIMUM_PHASE_DIFFERENCE_THRESHOLD = -240.0;
private static final double DEFAULT_AUTOMATON_A17_MAXIMUM_PHASE_DIFFERENCE_THRESHOLD = 240.0;
private static final double DEFAULT_AUTOMATON_A17_OBSERVATION_DURATION = -1;
private static final boolean DEFAULT_AUTOMATON_A56 = false;
private static final Path DEFAULT_AUTOMATON_A56_DETAILS_FILE = null;



private boolean automatonA11;
private boolean automatonA12;
private boolean automatonA14;
private boolean automatonA17;
private boolean automatonA56;
private boolean importExportRST;
private boolean importExportACMC;
private boolean LVLoadModeling;
Expand All @@ -60,12 +67,14 @@ public class DdExportConfig {
private double automatonA17MinimumPhaseDifferenceThreshold;
private double automatonA17MaximumPhaseDifferenceThreshold;
private double automatonA17ObservationDuration;
private Path automatonA56DetailsFile;

public static DdExportConfig load(PlatformConfig platformConfig) {
boolean automatonA11 = DEFAULT_AUTOMATON_A11;
boolean automatonA12 = DEFAULT_AUTOMATON_A12;
boolean automatonA14 = DEFAULT_AUTOMATON_A14;
boolean automatonA17 = DEFAULT_AUTOMATON_A17;
boolean automatonA56 = DEFAULT_AUTOMATON_A56;
boolean importExportRST = DEFAULT_RST;
boolean importExportACMC = DEFAULT_ACMC;
boolean lvLoadModeling = DEFAULT_LV_LOAD_MODELING;
Expand All @@ -83,6 +92,7 @@ public static DdExportConfig load(PlatformConfig platformConfig) {
double automatonA17MinimumPhaseDifferenceThreshold = DEFAULT_AUTOMATON_A17_MINIMUM_PHASE_DIFFERENCE_THRESHOLD;
double automatonA17MaximumPhaseDifferenceThreshold = DEFAULT_AUTOMATON_A17_MAXIMUM_PHASE_DIFFERENCE_THRESHOLD;
double automatonA17ObservationDuration = DEFAULT_AUTOMATON_A17_OBSERVATION_DURATION;
Path automatonA56DetailsFile = DEFAULT_AUTOMATON_A56_DETAILS_FILE;


if (platformConfig.moduleExists(MODULE_NAME)) {
Expand All @@ -91,10 +101,12 @@ public static DdExportConfig load(PlatformConfig platformConfig) {
automatonA12 = config.getBooleanProperty("automatonA12", DEFAULT_AUTOMATON_A12);
automatonA14 = config.getBooleanProperty("automatonA14", DEFAULT_AUTOMATON_A14);
automatonA17 = config.getBooleanProperty("automatonA17", DEFAULT_AUTOMATON_A17);
automatonA56 = config.getBooleanProperty("automatonA56", DEFAULT_AUTOMATON_A56);
automatonA17AngularReferenceGenerator = config.getStringProperty("automatonA17AngularReferenceGenerator", DEFAULT_AUTOMATON_A17_REFERENCE_GENERATOR);
automatonA17MinimumPhaseDifferenceThreshold = config.getDoubleProperty("automatonA17MinimumPhaseDifferenceThreshold", DEFAULT_AUTOMATON_A17_MINIMUM_PHASE_DIFFERENCE_THRESHOLD);
automatonA17MaximumPhaseDifferenceThreshold = config.getDoubleProperty("automatonA17MaximumPhaseDifferenceThreshold", DEFAULT_AUTOMATON_A17_MAXIMUM_PHASE_DIFFERENCE_THRESHOLD);
automatonA17ObservationDuration = config.getDoubleProperty("automatonA17ObservationDuration", DEFAULT_AUTOMATON_A17_OBSERVATION_DURATION);
automatonA56DetailsFile = automatonA56 ? config.getPathProperty("automatonA56DetailsFile") : config.getPathProperty("automatonA56DetailsFile", null);
importExportRST = config.getBooleanProperty("importExportRST", DEFAULT_RST);
importExportACMC = config.getBooleanProperty("importExportACMC", DEFAULT_ACMC);
lvLoadModeling = config.getBooleanProperty("LVLoadModeling", DEFAULT_LV_LOAD_MODELING);
Expand All @@ -115,6 +127,7 @@ public static DdExportConfig load(PlatformConfig platformConfig) {
}

return new DdExportConfig(automatonA11, automatonA12, automatonA14, automatonA17, automatonA17AngularReferenceGenerator, automatonA17MinimumPhaseDifferenceThreshold, automatonA17MaximumPhaseDifferenceThreshold, automatonA17ObservationDuration,
automatonA56, automatonA56DetailsFile,
importExportRST, importExportACMC, lvLoadModeling, rstRegulInjector, rstRegulGenerator, rstRegulGeneratorDelete,
acmcRegul, rstPilotGenerators, loadPatternAlpha, loadPatternBeta, gensPQfilter, exportMainCCOnly, noSwitch);
}
Expand All @@ -125,18 +138,21 @@ public static DdExportConfig load() {

public DdExportConfig() {
this(DEFAULT_AUTOMATON_A11, DEFAULT_AUTOMATON_A12, DEFAULT_AUTOMATON_A14, DEFAULT_AUTOMATON_A17, DEFAULT_AUTOMATON_A17_REFERENCE_GENERATOR, DEFAULT_AUTOMATON_A17_MINIMUM_PHASE_DIFFERENCE_THRESHOLD, DEFAULT_AUTOMATON_A17_MAXIMUM_PHASE_DIFFERENCE_THRESHOLD, DEFAULT_AUTOMATON_A17_OBSERVATION_DURATION,
DEFAULT_AUTOMATON_A56, DEFAULT_AUTOMATON_A56_DETAILS_FILE,
DEFAULT_RST, DEFAULT_ACMC, DEFAULT_LV_LOAD_MODELING, DEFAULT_RST_REGUL_INJECTOR, DEFAULT_RST_REGUL_GENERATOR, DEFAULT_RST_REGUL_GENERATOR_DELETE,
DEFAULT_ACMC_REGUL, DEFAULT_RST_PILOT_GENERATORS, DEFAULT_LOAD_PATTERN_ALPHA, DEFAULT_LOAD_PATTERN_BETA, DEFAULT_GENPQFILTER, DEFAULT_EXPORT_MAIN_CC_ONLY, DEFAULT_NOSWITCH);
}

public DdExportConfig(boolean automatonA11, boolean automatonA12, boolean automatonA14, boolean automatonA17, String automatonA17AngularReferenceGenerator, double automatonA17MinimumPhaseDifferenceThreshold, double automatonA17MaximumPhaseDifferenceThreshold, double automatonA17ObservationDuration,
boolean automatonA56, Path automatonA56DetailsFile,
boolean importExportRST, boolean importExportACMC, boolean lvLoadModeling, String rstRegulInjector,
String rstRegulGenerator, String rstRegulGeneratorDelete, String acmcRegul,
String rstPilotGenerators, float loadPatternAlpha, float loadPatternBeta, boolean gensPQfilter, boolean exportMainCCOnly, boolean noSwitch) {
this.automatonA11 = automatonA11;
this.automatonA12 = automatonA12;
this.automatonA14 = automatonA14;
this.automatonA17 = automatonA17;
this.automatonA56 = automatonA56;
this.importExportRST = importExportRST;
this.importExportACMC = importExportACMC;
this.LVLoadModeling = lvLoadModeling;
Expand All @@ -154,6 +170,7 @@ public DdExportConfig(boolean automatonA11, boolean automatonA12, boolean automa
this.automatonA17MinimumPhaseDifferenceThreshold = automatonA17MinimumPhaseDifferenceThreshold;
this.automatonA17MaximumPhaseDifferenceThreshold = automatonA17MaximumPhaseDifferenceThreshold;
this.automatonA17ObservationDuration = automatonA17ObservationDuration;
this.automatonA56DetailsFile = automatonA56DetailsFile;
}

public boolean getAutomatonA11() {
Expand All @@ -172,6 +189,10 @@ public boolean getAutomatonA17() {
return automatonA17;
}

public boolean getAutomatonA56() {
return automatonA56;
}

public boolean getExportRST() {
return importExportRST;
}
Expand Down Expand Up @@ -240,6 +261,10 @@ public double getAutomatonA17ObservationDuration() {
return automatonA17ObservationDuration;
}

public Path getDefaultAutomatonA56DetailsFile() {
return automatonA56DetailsFile;
}

public void setAutomatonA11(Boolean automatonA11) {
this.automatonA11 = automatonA11;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1897,6 +1897,24 @@ public void dumpDataAutomatons(SimulatorInst eurostagSim, DDBManager ddbmanager,
}

DdbDtaImpExp.dumpDataAutomatonA17(network, dtaOutStream, iidm2eurostagId, simulationParameters, configExport);

DdbDtaImpExp.dumpDataAutomatonA56(network, dtaOutStream, iidm2eurostagId, configExport);
}


public static void dumpDataAutomatonA56(Network network, PrintStream dtaOutStream, Map<String, String> iidm2eurostagId, DdExportConfig configExport) {
if (configExport.getAutomatonA56()) {
try {
Path a56DetailsXml = configExport.getDefaultAutomatonA56DetailsFile();
if (Files.exists(a56DetailsXml)) {
AutomatonA56.writeToDta(network, dtaOutStream, iidm2eurostagId, a56DetailsXml);
} else {
log.error("skipping A56 section: automaton details file {} does not exist", a56DetailsXml);
}
} catch (Exception e) {
log.error(e.getMessage(), e);
}
}
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,10 @@ private DtaParser(final String name) {
"equipment.name,seq.params"
});

componentsVariablesNames.put("A56", new String[]{
"BRANCH_ID,NO_BEATS,DELAY,INITIAL_VOLTAGE,BASE_VOLTAGE,TIME_CONSTANT,COMMENTS"
});

componentsVariablesNames.put("M21", new String[]{
"machine.type, type.fortescue, XMACOUP, fnum1, fnum2, falpha",
"machine.name,connection.node.name,type.power.assigned,PP,PQ,PN,RIFO,RIXFO,R0FO,R0XFO"
Expand Down Expand Up @@ -261,6 +265,10 @@ private DtaParser(final String name) {
"(18X,A8,1X,A52)"
});

componentsDescriptors.put("A56", new String[]{
"(A19,1X,F8,1X,F8,1X,F8,1X,F8,1X,F8,2X,A2)",
});

componentsDescriptors.put("M21", new String[]{
"(A3, A1, 1X, A1, 7X, F8, 1X, F8, 1X, A8)",
"(A8, 1X, A8, 1X, A1, 17X, F8, 1X, F8, 19X, F8, F8, 1X, F8, 1X, F8, 1X, F8)"
Expand Down Expand Up @@ -511,6 +519,7 @@ public static void dumpZone(EurostagRecord zone, PrintStream out) throws ParseEx
case "A12":
case "A14":
case "A17":
case "A56":
int acountl = 1;
String[] recordsFormattinga = componentsDescriptors.get(zone.typeName);
for (String string : recordsFormattinga) {
Expand Down

0 comments on commit 0314540

Please sign in to comment.