diff --git a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java index 2afea38ff..f0ebb4592 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java +++ b/java/src/main/java/com/powsybl/dataframe/network/NetworkDataframes.java @@ -15,7 +15,6 @@ import com.powsybl.dataframe.network.extensions.ExtensionDataframeKey; import com.powsybl.dataframe.update.UpdatingDataframe; import com.powsybl.iidm.network.*; -import com.powsybl.python.commons.PyPowsyblApiHeader; import com.powsybl.python.network.NetworkUtil; import com.powsybl.python.network.SideEnum; import com.powsybl.python.network.TemporaryLimitData; @@ -44,8 +43,6 @@ public final class NetworkDataframes { private static final Map EXTENSIONS_MAPPERS = NetworkExtensions.createExtensionsMappers(); - private static final String DEFAULT_OPERATIONAL_LIMIT_GROUP_ID = "DEFAULT"; - private NetworkDataframes() { } @@ -56,9 +53,6 @@ public static NetworkDataframeMapper getDataframeMapper(DataframeElementType typ private static Map createMappers() { Map mappers = new EnumMap<>(DataframeElementType.class); mappers.put(DataframeElementType.SUB_NETWORK, subNetworks()); - mappers.put(DataframeElementType.AREA, areas()); - mappers.put(DataframeElementType.AREA_VOLTAGE_LEVELS, areaVoltageLevels()); - mappers.put(DataframeElementType.AREA_BOUNDARIES, areaBoundaries()); mappers.put(DataframeElementType.BUS, buses(false)); mappers.put(DataframeElementType.BUS_FROM_BUS_BREAKER_VIEW, buses(true)); mappers.put(DataframeElementType.LINE, lines()); @@ -78,15 +72,14 @@ private static Map createMappers() mappers.put(DataframeElementType.SWITCH, switches()); mappers.put(DataframeElementType.VOLTAGE_LEVEL, voltageLevels()); mappers.put(DataframeElementType.SUBSTATION, substations()); - mappers.put(DataframeElementType.BUSBAR_SECTION, busbarSections()); + mappers.put(DataframeElementType.BUSBAR_SECTION, busBars()); mappers.put(DataframeElementType.HVDC_LINE, hvdcs()); mappers.put(DataframeElementType.RATIO_TAP_CHANGER_STEP, rtcSteps()); mappers.put(DataframeElementType.PHASE_TAP_CHANGER_STEP, ptcSteps()); mappers.put(DataframeElementType.RATIO_TAP_CHANGER, rtcs()); mappers.put(DataframeElementType.PHASE_TAP_CHANGER, ptcs()); mappers.put(DataframeElementType.REACTIVE_CAPABILITY_CURVE_POINT, reactiveCapabilityCurves()); - mappers.put(DataframeElementType.OPERATIONAL_LIMITS, operationalLimits(false)); - mappers.put(DataframeElementType.SELECTED_OPERATIONAL_LIMITS, operationalLimits(true)); + mappers.put(DataframeElementType.OPERATIONAL_LIMITS, operationalLimits()); mappers.put(DataframeElementType.ALIAS, aliases()); mappers.put(DataframeElementType.IDENTIFIABLE, identifiables()); mappers.put(DataframeElementType.INJECTION, injections()); @@ -95,55 +88,55 @@ private static Map createMappers() return Collections.unmodifiableMap(mappers); } - static > ToDoubleBiFunction getPerUnitP() { + static > ToDoubleBiFunction getPerUnitP() { return (inj, context) -> perUnitPQ(context, inj.getTerminal().getP()); } - static > ToDoubleFunction getOppositeP() { + static ToDoubleFunction getOppositeP() { return inj -> -inj.getTerminal().getP(); } - static > ToDoubleBiFunction getPerUnitQ() { + static > ToDoubleBiFunction getPerUnitQ() { return (inj, context) -> perUnitPQ(context, inj.getTerminal().getQ()); } - static > DoubleSeriesMapper.DoubleUpdater setPerUnitP() { + static > DoubleSeriesMapper.DoubleUpdater setPerUnitP() { return (inj, p, context) -> inj.getTerminal().setP(unPerUnitPQ(context, p)); } - static > DoubleSeriesMapper.DoubleUpdater setPerUnitQ() { + static > DoubleSeriesMapper.DoubleUpdater setPerUnitQ() { return (inj, q, context) -> inj.getTerminal().setQ(unPerUnitPQ(context, q)); } - static > ToDoubleBiFunction getPerUnitP1() { + static > ToDoubleBiFunction getPerUnitP1() { return (b, context) -> perUnitPQ(context, b.getTerminal1().getP()); } - static > ToDoubleBiFunction getPerUnitQ1() { + static > ToDoubleBiFunction getPerUnitQ1() { return (b, context) -> perUnitPQ(context, b.getTerminal1().getQ()); } - static > DoubleSeriesMapper.DoubleUpdater setPerUnitP1() { + static > DoubleSeriesMapper.DoubleUpdater setPerUnitP1() { return (b, p, context) -> b.getTerminal1().setP(unPerUnitPQ(context, p)); } - static > DoubleSeriesMapper.DoubleUpdater setPerUnitQ1() { + static > DoubleSeriesMapper.DoubleUpdater setPerUnitQ1() { return (b, q, context) -> b.getTerminal1().setQ(unPerUnitPQ(context, q)); } - static > ToDoubleBiFunction getPerUnitP2() { + static > ToDoubleBiFunction getPerUnitP2() { return (b, context) -> perUnitPQ(context, b.getTerminal2().getP()); } - static > ToDoubleBiFunction getPerUnitQ2() { + static > ToDoubleBiFunction getPerUnitQ2() { return (b, context) -> perUnitPQ(context, b.getTerminal2().getQ()); } - static > DoubleSeriesMapper.DoubleUpdater setPerUnitP2() { + static > DoubleSeriesMapper.DoubleUpdater setPerUnitP2() { return (b, p, context) -> b.getTerminal2().setP(unPerUnitPQ(context, p)); } - static > DoubleSeriesMapper.DoubleUpdater setPerUnitQ2() { + static > DoubleSeriesMapper.DoubleUpdater setPerUnitQ2() { return (b, q, context) -> b.getTerminal2().setQ(unPerUnitPQ(context, q)); } @@ -268,7 +261,7 @@ public static ToDoubleBiFunction ifExistsDoub static NetworkDataframeMapper generators() { return NetworkDataframeMapperBuilder.ofStream(Network::getGeneratorStream, getOrThrow(Network::getGenerator, "Generator")) .stringsIndex("id", Generator::getId) - .strings("name", g -> g.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", g -> g.getOptionalName().orElse("")) .enums("energy_source", EnergySource.class, Generator::getEnergySource, Generator::setEnergySource) .doubles("target_p", (g, context) -> perUnitPQ(context, g.getTargetP()), (g, targetP, context) -> g.setTargetP(unPerUnitPQ(context, targetP))) .doubles("min_p", (g, context) -> perUnitPQ(context, g.getMinP()), (g, minP, context) -> g.setMinP(unPerUnitPQ(context, minP))) @@ -309,26 +302,11 @@ private static NetworkDataframeMapper subNetworks() { .build(); } - private static NetworkDataframeMapper areas() { - return NetworkDataframeMapperBuilder.ofStream(Network::getAreaStream, - getOrThrow(Network::getArea, "Area")) - .stringsIndex("id", Identifiable::getId) - .strings("name", a -> a.getOptionalName().orElse(""), Identifiable::setName) - .strings("area_type", Area::getAreaType) - .doubles("interchange_target", (a, context) -> perUnitPQ(context, a.getInterchangeTarget().orElse(Double.NaN)), (a, p, context) -> a.setInterchangeTarget(unPerUnitPQ(context, p))) - .doubles("interchange", (a, context) -> perUnitPQ(context, a.getInterchange())) - .doubles("ac_interchange", (a, context) -> perUnitPQ(context, a.getAcInterchange())) - .doubles("dc_interchange", (a, context) -> perUnitPQ(context, a.getDcInterchange())) - .booleans("fictitious", Identifiable::isFictitious, Identifiable::setFictitious, false) - .addProperties() - .build(); - } - static NetworkDataframeMapper buses(boolean busBreakerView) { return NetworkDataframeMapperBuilder.ofStream(n -> busBreakerView ? n.getBusBreakerView().getBusStream() : n.getBusView().getBusStream(), getOrThrow((b, id) -> b.getBusView().getBus(id), "Bus")) .stringsIndex("id", Bus::getId) - .strings("name", b -> b.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", b -> b.getOptionalName().orElse("")) .doubles("v_mag", (b, context) -> perUnitV(context, b.getV(), b), (b, v, context) -> b.setV(unPerUnitV(context, v, b))) .doubles("v_angle", (b, context) -> perUnitAngle(context, b.getAngle()), (b, vAngle, context) -> b.setAngle(unPerUnitAngle(context, vAngle))) @@ -343,7 +321,7 @@ static NetworkDataframeMapper buses(boolean busBreakerView) { static NetworkDataframeMapper loads() { return NetworkDataframeMapperBuilder.ofStream(Network::getLoadStream, getOrThrow(Network::getLoad, "Load")) .stringsIndex("id", Load::getId) - .strings("name", l -> l.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", l -> l.getOptionalName().orElse("")) .enums("type", LoadType.class, Load::getLoadType) .doubles("p0", (l, context) -> perUnitPQ(context, l.getP0()), (l, p, context) -> l.setP0(unPerUnitPQ(context, p))) .doubles("q0", (l, context) -> perUnitPQ(context, l.getQ0()), (l, q, context) -> l.setQ0(unPerUnitPQ(context, q))) @@ -363,7 +341,7 @@ static NetworkDataframeMapper loads() { static NetworkDataframeMapper batteries() { return NetworkDataframeMapperBuilder.ofStream(Network::getBatteryStream, getOrThrow(Network::getBattery, "Battery")) .stringsIndex("id", Battery::getId) - .strings("name", b -> b.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", b -> b.getOptionalName().orElse("")) .doubles("max_p", (b, context) -> perUnitPQ(context, b.getMaxP()), (b, maxP, context) -> b.setMaxP(unPerUnitPQ(context, maxP))) .doubles("min_p", (b, context) -> perUnitPQ(context, b.getMinP()), (b, minP, context) -> b.setMinP(unPerUnitPQ(context, minP))) .doubles("min_q", ifExistsDoublePerUnitPQ(NetworkDataframes::getMinMaxReactiveLimits, MinMaxReactiveLimits::getMinQ), @@ -389,7 +367,7 @@ static NetworkDataframeMapper batteries() { static NetworkDataframeMapper shunts() { return NetworkDataframeMapperBuilder.ofStream(Network::getShuntCompensatorStream, getOrThrow(Network::getShuntCompensator, "Shunt compensator")) .stringsIndex("id", ShuntCompensator::getId) - .strings("name", sc -> sc.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", sc -> sc.getOptionalName().orElse("")) .doubles("g", (shunt, context) -> perUnitG(context, shunt)) .doubles("b", (shunt, context) -> perUnitB(context, shunt)) .enums("model_type", ShuntCompensatorModelType.class, ShuntCompensator::getModelType) @@ -478,7 +456,7 @@ private static ShuntCompensatorLinearModel checkLinearModel(Network network, Str static NetworkDataframeMapper lines() { return NetworkDataframeMapperBuilder.ofStream(Network::getLineStream, getOrThrow(Network::getLine, "Line")) .stringsIndex("id", Line::getId) - .strings("name", l -> l.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", l -> l.getOptionalName().orElse("")) .doubles("r", (line, context) -> perUnitR(context, line), (line, r, context) -> line.setR(unPerUnitRX(context, line, r))) .doubles("x", (line, context) -> PerUnitUtil.perUnitX(context, line), @@ -508,10 +486,6 @@ static NetworkDataframeMapper lines() { .booleans("connected1", l -> l.getTerminal1().isConnected(), connectBranchSide1()) .booleans("connected2", l -> l.getTerminal2().isConnected(), connectBranchSide2()) .booleans("fictitious", Identifiable::isFictitious, Identifiable::setFictitious, false) - .strings("selected_limits_group_1", line -> line.getSelectedOperationalLimitsGroupId1().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - Line::setSelectedOperationalLimitsGroup1, false) - .strings("selected_limits_group_2", line -> line.getSelectedOperationalLimitsGroupId2().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - Line::setSelectedOperationalLimitsGroup2, false) .addProperties() .build(); } @@ -519,7 +493,7 @@ static NetworkDataframeMapper lines() { static NetworkDataframeMapper twoWindingTransformers() { return NetworkDataframeMapperBuilder.ofStream(Network::getTwoWindingsTransformerStream, getOrThrow(Network::getTwoWindingsTransformer, "Two windings transformer")) .stringsIndex("id", TwoWindingsTransformer::getId) - .strings("name", twt -> twt.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", twt -> twt.getOptionalName().orElse("")) .doubles("r", (twt, context) -> perUnitRX(context, twt.getR(), twt), (twt, r, context) -> twt.setR(unPerUnitRX(context, twt, r))) .doubles("x", (twt, context) -> perUnitRX(context, twt.getX(), twt), (twt, x, context) -> twt.setX(unPerUnitRX(context, twt, x))) .doubles("g", (twt, context) -> perUnitBG(context, twt, twt.getG()), (twt, g, context) -> twt.setG(unPerUnitBG(context, twt, g))) @@ -546,10 +520,6 @@ static NetworkDataframeMapper twoWindingTransformers() { .booleans("connected1", twt -> twt.getTerminal1().isConnected(), connectBranchSide1()) .booleans("connected2", twt -> twt.getTerminal2().isConnected(), connectBranchSide2()) .booleans("fictitious", Identifiable::isFictitious, Identifiable::setFictitious, false) - .strings("selected_limits_group_1", twt -> twt.getSelectedOperationalLimitsGroupId1().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - TwoWindingsTransformer::setSelectedOperationalLimitsGroup1, false) - .strings("selected_limits_group_2", twt -> twt.getSelectedOperationalLimitsGroupId2().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - TwoWindingsTransformer::setSelectedOperationalLimitsGroup2, false) .addProperties() .build(); } @@ -557,7 +527,7 @@ static NetworkDataframeMapper twoWindingTransformers() { static NetworkDataframeMapper threeWindingTransformers() { return NetworkDataframeMapperBuilder.ofStream(Network::getThreeWindingsTransformerStream, getOrThrow(Network::getThreeWindingsTransformer, "Three windings transformer")) .stringsIndex("id", ThreeWindingsTransformer::getId) - .strings("name", twt -> twt.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", twt -> twt.getOptionalName().orElse("")) .doubles("rated_u0", (twt, context) -> context.isPerUnit() ? 1 : twt.getRatedU0()) .doubles("r1", (twt, context) -> perUnitRX(context, twt.getLeg1().getR(), twt), (twt, r1, context) -> twt.getLeg1().setR(unPerUnitRX(context, twt, r1))) .doubles("x1", (twt, context) -> perUnitRX(context, twt.getLeg1().getX(), twt), (twt, x1, context) -> twt.getLeg1().setX(unPerUnitRX(context, twt, x1))) @@ -575,8 +545,6 @@ static NetworkDataframeMapper threeWindingTransformers() { .strings("bus_breaker_bus1_id", twt -> getBusBreakerViewBusId(twt.getLeg1().getTerminal()), (twt, id) -> setBusBreakerViewBusId(twt.getLeg1().getTerminal(), id), false) .ints("node1", twt -> getNode(twt.getLeg1().getTerminal()), false) .booleans("connected1", g -> g.getLeg1().getTerminal().isConnected(), connectLeg1()) - .strings("selected_limits_group_1", twt -> twt.getLeg1().getSelectedOperationalLimitsGroupId().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - (twt, groupId) -> twt.getLeg1().setSelectedOperationalLimitsGroup(groupId), false) .doubles("r2", (twt, context) -> perUnitRX(context, twt.getLeg2().getR(), twt), (twt, r2, context) -> twt.getLeg2().setR(unPerUnitRX(context, twt, r2))) .doubles("x2", (twt, context) -> perUnitRX(context, twt.getLeg2().getX(), twt), (twt, x2, context) -> twt.getLeg2().setX(unPerUnitRX(context, twt, x2))) .doubles("g2", (twt, context) -> perUnitBG(context, twt.getLeg2().getG(), twt), (twt, g2, context) -> twt.getLeg2().setG(unPerUnitBG(context, twt, g2))) @@ -593,8 +561,6 @@ static NetworkDataframeMapper threeWindingTransformers() { .strings("bus_breaker_bus2_id", twt -> getBusBreakerViewBusId(twt.getLeg2().getTerminal()), (twt, id) -> setBusBreakerViewBusId(twt.getLeg2().getTerminal(), id), false) .ints("node2", twt -> getNode(twt.getLeg2().getTerminal()), false) .booleans("connected2", g -> g.getLeg2().getTerminal().isConnected(), connectLeg2()) - .strings("selected_limits_group_2", twt -> twt.getLeg2().getSelectedOperationalLimitsGroupId().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - (twt, groupId) -> twt.getLeg2().setSelectedOperationalLimitsGroup(groupId), false) .doubles("r3", (twt, context) -> perUnitRX(context, twt.getLeg3().getR(), twt), (twt, r3, context) -> twt.getLeg3().setR(unPerUnitRX(context, twt, r3))) .doubles("x3", (twt, context) -> perUnitRX(context, twt.getLeg3().getX(), twt), (twt, x3, context) -> twt.getLeg3().setX(unPerUnitRX(context, twt, x3))) .doubles("g3", (twt, context) -> perUnitBG(context, twt.getLeg3().getG(), twt), (twt, g3, context) -> twt.getLeg3().setG(unPerUnitBG(context, twt, g3))) @@ -611,8 +577,6 @@ static NetworkDataframeMapper threeWindingTransformers() { .strings("bus_breaker_bus3_id", twt -> getBusBreakerViewBusId(twt.getLeg3().getTerminal()), (twt, id) -> setBusBreakerViewBusId(twt.getLeg3().getTerminal(), id), false) .ints("node3", twt -> getNode(twt.getLeg3().getTerminal()), false) .booleans("connected3", twt -> twt.getLeg3().getTerminal().isConnected(), connectLeg3()) - .strings("selected_limits_group_3", twt -> twt.getLeg3().getSelectedOperationalLimitsGroupId().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - (twt, groupId) -> twt.getLeg3().setSelectedOperationalLimitsGroup(groupId), false) .booleans("fictitious", Identifiable::isFictitious, Identifiable::setFictitious, false) .addProperties() .build(); @@ -621,7 +585,7 @@ static NetworkDataframeMapper threeWindingTransformers() { static NetworkDataframeMapper danglingLines() { return NetworkDataframeMapperBuilder.ofStream(network -> network.getDanglingLineStream(), getOrThrow(Network::getDanglingLine, "Dangling line")) .stringsIndex("id", DanglingLine::getId) - .strings("name", dl -> dl.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", dl -> dl.getOptionalName().orElse("")) .doubles("r", (dl, context) -> perUnitRX(context, dl.getR(), dl.getTerminal()), (dl, r, context) -> dl.setR(unPerUnitRX(context, dl.getTerminal(), r))) .doubles("x", (dl, context) -> perUnitRX(context, dl.getX(), dl.getTerminal()), (dl, x, context) -> dl.setX(unPerUnitRX(context, dl.getTerminal(), x))) .doubles("g", (dl, context) -> perUnitG(context, dl), (dl, g, context) -> dl.setG(unPerUnitG(context, dl, g))) @@ -647,6 +611,18 @@ static NetworkDataframeMapper danglingLines() { .strings("tie_line_id", dl -> dl.getTieLine().map(Identifiable::getId).orElse("")) .strings("selected_limits_group", dl -> dl.getSelectedOperationalLimitsGroupId().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), DanglingLine::setSelectedOperationalLimitsGroup, false) + .doubles("min_p", (dl, context) -> perUnitPQ(context, Optional.ofNullable(dl.getGeneration()).map(DanglingLine.Generation::getMinP).orElse(NaN)), + (dl, minP, context) -> Optional.ofNullable(dl.getGeneration()).ifPresent(gen -> gen.setMinP(unPerUnitPQ(context, minP))), false) + .doubles("max_p", (dl, context) -> perUnitPQ(context, Optional.ofNullable(dl.getGeneration()).map(DanglingLine.Generation::getMaxP).orElse(NaN)), + (dl, maxP, context) -> Optional.ofNullable(dl.getGeneration()).ifPresent(gen -> gen.setMaxP(unPerUnitPQ(context, maxP))), false) + .doubles("target_p", (dl, context) -> perUnitPQ(context, Optional.ofNullable(dl.getGeneration()).map(DanglingLine.Generation::getTargetP).orElse(NaN)), + (dl, targetP, context) -> Optional.ofNullable(dl.getGeneration()).ifPresent(gen -> gen.setTargetP(unPerUnitPQ(context, targetP))), false) + .doubles("target_q", (dl, context) -> perUnitPQ(context, Optional.ofNullable(dl.getGeneration()).map(DanglingLine.Generation::getTargetQ).orElse(NaN)), + (dl, targetQ, context) -> Optional.ofNullable(dl.getGeneration()).ifPresent(gen -> gen.setTargetQ(unPerUnitPQ(context, targetQ))), false) + .doubles("target_v", (dl, context) -> perUnitV(context, Optional.ofNullable(dl.getGeneration()).map(DanglingLine.Generation::getTargetV).orElse(NaN), dl.getTerminal()), + (dl, targetV, context) -> Optional.ofNullable(dl.getGeneration()).ifPresent(gen -> gen.setTargetV(unPerUnitV(context, targetV, dl.getTerminal()))), false) + .booleans("voltage_regulator_on", dl -> Optional.ofNullable(dl.getGeneration()).map(DanglingLine.Generation::isVoltageRegulationOn).orElse(false), + (dl, voltageRegulatorOn) -> Optional.ofNullable(dl.getGeneration()).ifPresent(gen -> gen.setVoltageRegulationOn(voltageRegulatorOn)), false) .addProperties() .build(); } @@ -654,7 +630,7 @@ static NetworkDataframeMapper danglingLines() { static NetworkDataframeMapper tieLines() { return NetworkDataframeMapperBuilder.ofStream(Network::getTieLineStream, getOrThrow(Network::getTieLine, "Tie line")) .stringsIndex("id", TieLine::getId) - .strings("name", tl -> tl.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", tl -> tl.getOptionalName().orElse("")) .strings("dangling_line1_id", tl -> tl.getDanglingLine1().getId()) .strings("dangling_line2_id", tl -> tl.getDanglingLine2().getId()) .strings("pairing_key", tl -> Objects.toString(tl.getPairingKey(), "")) @@ -667,7 +643,7 @@ static NetworkDataframeMapper tieLines() { static NetworkDataframeMapper lccs() { return NetworkDataframeMapperBuilder.ofStream(Network::getLccConverterStationStream, getOrThrow(Network::getLccConverterStation, "LCC converter station")) .stringsIndex("id", LccConverterStation::getId) - .strings("name", st -> st.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", st -> st.getOptionalName().orElse("")) .doubles("power_factor", (st, context) -> st.getPowerFactor(), (lcc, v, context) -> lcc.setPowerFactor((float) v)) .doubles("loss_factor", (st, context) -> st.getLossFactor(), (lcc, v, context) -> lcc.setLossFactor((float) v)) .doubles("p", getPerUnitP(), setPerUnitP()) @@ -686,7 +662,7 @@ static NetworkDataframeMapper lccs() { static NetworkDataframeMapper vscs() { return NetworkDataframeMapperBuilder.ofStream(Network::getVscConverterStationStream, getOrThrow(Network::getVscConverterStation, "VSC converter station")) .stringsIndex("id", VscConverterStation::getId) - .strings("name", st -> st.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", st -> st.getOptionalName().orElse("")) .doubles("loss_factor", (vsc, context) -> vsc.getLossFactor(), (vscConverterStation, lf, context) -> vscConverterStation.setLossFactor((float) lf)) .doubles("min_q", ifExistsDoublePerUnitPQ(NetworkDataframes::getMinMaxReactiveLimits, MinMaxReactiveLimits::getMinQ), setPerUnitMinQ()) .doubles("max_q", ifExistsDoublePerUnitPQ(NetworkDataframes::getMinMaxReactiveLimits, MinMaxReactiveLimits::getMaxQ), setPerUnitMaxQ()) @@ -716,7 +692,7 @@ static NetworkDataframeMapper vscs() { private static NetworkDataframeMapper svcs() { return NetworkDataframeMapperBuilder.ofStream(Network::getStaticVarCompensatorStream, getOrThrow(Network::getStaticVarCompensator, "Static var compensator")) .stringsIndex("id", StaticVarCompensator::getId) - .strings("name", svc -> svc.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", svc -> svc.getOptionalName().orElse("")) .doubles("b_min", (svc, context) -> svc.getBmin(), (svc, bMin, context) -> svc.setBmin(bMin)) .doubles("b_max", (svc, context) -> svc.getBmax(), (svc, bMax, context) -> svc.setBmax(bMax)) .doubles("target_v", (svc, context) -> perUnitTargetV(context, svc.getVoltageSetpoint(), svc.getRegulatingTerminal(), svc.getTerminal()), @@ -777,7 +753,7 @@ private static int getNode2(Switch s) { private static NetworkDataframeMapper switches() { return NetworkDataframeMapperBuilder.ofStream(Network::getSwitchStream, getOrThrow(Network::getSwitch, "Switch")) .stringsIndex("id", Switch::getId) - .strings("name", s -> s.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", s -> s.getOptionalName().orElse("")) .enums("kind", SwitchKind.class, Switch::getKind) .booleans("open", Switch::isOpen, Switch::setOpen) .booleans("retained", Switch::isRetained, Switch::setRetained) @@ -794,7 +770,7 @@ private static NetworkDataframeMapper switches() { private static NetworkDataframeMapper voltageLevels() { return NetworkDataframeMapperBuilder.ofStream(Network::getVoltageLevelStream, getOrThrow(Network::getVoltageLevel, "Voltage level")) .stringsIndex("id", VoltageLevel::getId) - .strings("name", vl -> vl.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", vl -> vl.getOptionalName().orElse("")) .strings("substation_id", vl -> vl.getSubstation().map(Identifiable::getId).orElse("")) .doubles("nominal_v", (vl, context) -> vl.getNominalV(), (vl, nominalV, context) -> vl.setNominalV(nominalV)) .doubles("high_voltage_limit", (vl, context) -> perUnitV(context, vl.getHighVoltageLimit(), vl.getNominalV()), @@ -810,7 +786,7 @@ private static NetworkDataframeMapper voltageLevels() { private static NetworkDataframeMapper substations() { return NetworkDataframeMapperBuilder.ofStream(Network::getSubstationStream, getOrThrow(Network::getSubstation, "Substation")) .stringsIndex("id", Identifiable::getId) - .strings("name", s -> s.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", s -> s.getOptionalName().orElse("")) .strings("TSO", Substation::getTso, Substation::setTso) .strings("geo_tags", substation -> String.join(",", substation.getGeographicalTags())) .enums("country", Country.class, s -> s.getCountry().orElse(null), Substation::setCountry) @@ -819,10 +795,10 @@ private static NetworkDataframeMapper substations() { .build(); } - private static NetworkDataframeMapper busbarSections() { + private static NetworkDataframeMapper busBars() { return NetworkDataframeMapperBuilder.ofStream(Network::getBusbarSectionStream, getOrThrow(Network::getBusbarSection, "Bus bar section")) .stringsIndex("id", BusbarSection::getId) - .strings("name", bbs -> bbs.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", bbs -> bbs.getOptionalName().orElse("")) .doubles("v", (busbar, context) -> perUnitV(context, busbar.getV(), busbar.getTerminal())) .doubles("angle", (busbar, context) -> perUnitAngle(context, busbar.getAngle())) .strings("voltage_level_id", bbs -> bbs.getTerminal().getVoltageLevel().getId()) @@ -837,7 +813,7 @@ private static NetworkDataframeMapper hvdcs() { return NetworkDataframeMapperBuilder.ofStream(Network::getHvdcLineStream, getOrThrow(Network::getHvdcLine, "HVDC line")) .stringsIndex("id", HvdcLine::getId) - .strings("name", l -> l.getOptionalName().orElse(""), Identifiable::setName) + .strings("name", l -> l.getOptionalName().orElse("")) .enums("converters_mode", HvdcLine.ConvertersMode.class, HvdcLine::getConvertersMode, HvdcLine::setConvertersMode) .doubles("target_p", (hvdc, context) -> perUnitPQ(context, hvdc.getActivePowerSetpoint()), (hvdc, aps, context) -> hvdc.setActivePowerSetpoint(unPerUnitPQ(context, aps))) @@ -862,16 +838,16 @@ private static NetworkDataframeMapper rtcSteps() { return NetworkDataframeMapperBuilder.ofStream(ratioTapChangerSteps, NetworkDataframes::getRatioTapChangers) .stringsIndex("id", triple -> triple.getLeft().getId()) .intsIndex("position", Triple::getRight) - .doubles("rho", (p, context) -> p.getMiddle().getStep(p.getRight()).getRho(), - (p, rho, context) -> p.getMiddle().getStep(p.getRight()).setRho(rho)) - .doubles("r", (p, context) -> p.getMiddle().getStep(p.getRight()).getR(), - (p, r, context) -> p.getMiddle().getStep(p.getRight()).setR(r)) - .doubles("x", (p, context) -> p.getMiddle().getStep(p.getRight()).getX(), - (p, x, context) -> p.getMiddle().getStep(p.getRight()).setX(x)) - .doubles("g", (p, context) -> p.getMiddle().getStep(p.getRight()).getG(), - (p, g, context) -> p.getMiddle().getStep(p.getRight()).setG(g)) - .doubles("b", (p, context) -> p.getMiddle().getStep(p.getRight()).getB(), - (p, b, context) -> p.getMiddle().getStep(p.getRight()).setB(b)) + .doubles("rho", (p, context) -> perUnitRho(context, p.getLeft(), p.getMiddle().getStep(p.getRight()).getRho()), + (p, rho, context) -> p.getMiddle().getStep(p.getRight()).setRho(unPerUnitRho(context, p.getLeft(), rho))) + .doubles("r", (p, context) -> perUnitRX(context, p.getMiddle().getStep(p.getRight()).getR(), p.getLeft()), + (p, r, context) -> p.getMiddle().getStep(p.getRight()).setR(unPerUnitRX(context, p.getLeft(), r))) + .doubles("x", (p, context) -> perUnitRX(context, p.getMiddle().getStep(p.getRight()).getX(), p.getLeft()), + (p, x, context) -> p.getMiddle().getStep(p.getRight()).setX(unPerUnitRX(context, p.getLeft(), x))) + .doubles("g", (p, context) -> perUnitBG(context, p.getLeft(), p.getMiddle().getStep(p.getRight()).getG()), + (p, g, context) -> p.getMiddle().getStep(p.getRight()).setG(unPerUnitBG(context, p.getLeft(), g))) + .doubles("b", (p, context) -> perUnitBG(context, p.getLeft(), p.getMiddle().getStep(p.getRight()).getB()), + (p, b, context) -> p.getMiddle().getStep(p.getRight()).setB(unPerUnitBG(context, p.getLeft(), b))) .build(); } @@ -893,18 +869,18 @@ private static NetworkDataframeMapper ptcSteps() { return NetworkDataframeMapperBuilder.ofStream(phaseTapChangerSteps, NetworkDataframes::getPhaseTapChangers) .stringsIndex("id", triple -> triple.getLeft().getId()) .intsIndex("position", Triple::getRight) - .doubles("rho", (p, context) -> p.getMiddle().getStep(p.getRight()).getRho(), - (p, rho, context) -> p.getMiddle().getStep(p.getRight()).setRho(rho)) + .doubles("rho", (p, context) -> perUnitRho(context, p.getLeft(), p.getMiddle().getStep(p.getRight()).getRho()), + (p, rho, context) -> p.getMiddle().getStep(p.getRight()).setRho(unPerUnitRho(context, p.getLeft(), rho))) .doubles("alpha", (p, context) -> perUnitAngle(context, p.getMiddle().getStep(p.getRight()).getAlpha()), (p, alpha, context) -> p.getMiddle().getStep(p.getRight()).setAlpha(unPerUnitAngle(context, alpha))) - .doubles("r", (p, context) -> p.getMiddle().getStep(p.getRight()).getR(), - (p, r, context) -> p.getMiddle().getStep(p.getRight()).setR(r)) - .doubles("x", (p, context) -> p.getMiddle().getStep(p.getRight()).getX(), - (p, x, context) -> p.getMiddle().getStep(p.getRight()).setX(x)) - .doubles("g", (p, context) -> p.getMiddle().getStep(p.getRight()).getG(), - (p, g, context) -> p.getMiddle().getStep(p.getRight()).setG(g)) - .doubles("b", (p, context) -> p.getMiddle().getStep(p.getRight()).getB(), - (p, b, context) -> p.getMiddle().getStep(p.getRight()).setB(b)) + .doubles("r", (p, context) -> perUnitRX(context, p.getMiddle().getStep(p.getRight()).getR(), p.getLeft()), + (p, r, context) -> p.getMiddle().getStep(p.getRight()).setR(unPerUnitRX(context, p.getLeft(), r))) + .doubles("x", (p, context) -> perUnitRX(context, p.getMiddle().getStep(p.getRight()).getX(), p.getLeft()), + (p, x, context) -> p.getMiddle().getStep(p.getRight()).setX(unPerUnitRX(context, p.getLeft(), x))) + .doubles("g", (p, context) -> perUnitBG(context, p.getLeft(), p.getMiddle().getStep(p.getRight()).getG()), + (p, g, context) -> p.getMiddle().getStep(p.getRight()).setG(unPerUnitBG(context, p.getLeft(), g))) + .doubles("b", (p, context) -> perUnitBG(context, p.getLeft(), p.getMiddle().getStep(p.getRight()).getB()), + (p, b, context) -> p.getMiddle().getStep(p.getRight()).setB(unPerUnitBG(context, p.getLeft(), b))) .build(); } @@ -993,14 +969,10 @@ static NetworkDataframeMapper injections() { .stringsIndex("id", Injection::getId) .strings("type", injection -> injection.getType().toString()) .strings("voltage_level_id", injection -> injection.getTerminal().getVoltageLevel().getId()) - .ints("node", g -> getNode(g.getTerminal()), false) .strings("bus_breaker_bus_id", injection -> getBusBreakerViewBusId(injection.getTerminal()), (injection, id) -> setBusBreakerViewBusId(injection.getTerminal(), id), false) .booleans("connected", injection -> injection.getTerminal().isConnected(), connectInjection()) .strings("bus_id", injection -> injection.getTerminal().getBusView().getBus() == null ? "" : injection.getTerminal().getBusView().getBus().getId()) - .doubles("p", getPerUnitP(), setPerUnitP()) - .doubles("q", getPerUnitQ(), setPerUnitQ()) - .doubles("i", (l, context) -> perUnitI(context, l.getTerminal())) .build(); } @@ -1009,29 +981,17 @@ static NetworkDataframeMapper branches() { .stringsIndex("id", Branch::getId) .strings("type", branch -> branch.getType().toString()) .strings("voltage_level1_id", branch -> branch.getTerminal1().getVoltageLevel().getId()) - .ints("node1", g -> getNode(g.getTerminal1()), false) .strings("bus_breaker_bus1_id", branch -> getBusBreakerViewBusId(branch.getTerminal1()), (branch, id) -> setBusBreakerViewBusId(branch.getTerminal1(), id), false) .strings("bus1_id", branch -> branch.getTerminal1().getBusView().getBus() == null ? "" : branch.getTerminal1().getBusView().getBus().getId()) .booleans("connected1", branch -> branch.getTerminal1().isConnected(), (branch, connected) -> setConnected(branch.getTerminal1(), connected)) .strings("voltage_level2_id", branch -> branch.getTerminal2().getVoltageLevel().getId()) - .ints("node2", g -> getNode(g.getTerminal2()), false) .strings("bus_breaker_bus2_id", branch -> getBusBreakerViewBusId(branch.getTerminal2()), (branch, id) -> setBusBreakerViewBusId(branch.getTerminal2(), id), false) .strings("bus2_id", branch -> branch.getTerminal2().getBusView().getBus() == null ? "" : branch.getTerminal2().getBusView().getBus().getId()) .booleans("connected2", branch -> branch.getTerminal2().isConnected(), (branch, connected) -> setConnected(branch.getTerminal2(), connected)) - .doubles("p1", getPerUnitP1(), setPerUnitP1()) - .doubles("q1", getPerUnitQ1(), setPerUnitQ1()) - .doubles("i1", (branch, context) -> perUnitI(context, branch.getTerminal1())) - .doubles("p2", getPerUnitP2(), setPerUnitP2()) - .doubles("q2", getPerUnitQ2(), setPerUnitQ2()) - .doubles("i2", (branch, context) -> perUnitI(context, branch.getTerminal2())) - .strings("selected_limits_group_1", branch -> (String) branch.getSelectedOperationalLimitsGroupId1().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - Branch::setSelectedOperationalLimitsGroup1, false) - .strings("selected_limits_group_2", branch -> (String) branch.getSelectedOperationalLimitsGroupId2().orElse(DEFAULT_OPERATIONAL_LIMIT_GROUP_ID), - Branch::setSelectedOperationalLimitsGroup2, false) .build(); } @@ -1124,32 +1084,12 @@ private static String getTerminalSideStr(Branch branch, Terminal terminal) { return ""; } - private static String getTerminalSideStr(ThreeWindingsTransformer t3wt, Terminal terminal) { - if (terminal == t3wt.getLeg1().getTerminal()) { - return ThreeSides.ONE.name(); - } else if (terminal == t3wt.getLeg2().getTerminal()) { - return ThreeSides.TWO.name(); - } else if (terminal == t3wt.getLeg3().getTerminal()) { - return ThreeSides.THREE.name(); - } - return ""; - } - - private static String getTerminalSideStr(Identifiable identifiable, Terminal terminal) { - if (identifiable instanceof Branch branch) { - return getTerminalSideStr(branch, terminal); - } else if (identifiable instanceof ThreeWindingsTransformer t3wt) { - return getTerminalSideStr(t3wt, terminal); - } - return ""; - } - static void setPhaseTapChangerRegulatedSide(TwoWindingsTransformer transformer, String side) { transformer.getPhaseTapChanger().setRegulationTerminal(getBranchTerminal(transformer, side)); } - private static NetworkDataframeMapper operationalLimits(boolean onlyActive) { - return NetworkDataframeMapperBuilder.ofStream(onlyActive ? NetworkUtil::getSelectedLimits : NetworkUtil::getLimits) + private static NetworkDataframeMapper operationalLimits() { + return NetworkDataframeMapperBuilder.ofStream(NetworkUtil::getLimits) .stringsIndex("element_id", TemporaryLimitData::getId) .enums("element_type", IdentifiableType.class, TemporaryLimitData::getElementType) .enums("side", TemporaryLimitData.Side.class, TemporaryLimitData::getSide) @@ -1158,8 +1098,6 @@ private static NetworkDataframeMapper operationalLimits(boolean onlyActive) { .doubles("value", TemporaryLimitData::getValue) .ints("acceptable_duration", TemporaryLimitData::getAcceptableDuration) .booleans("fictitious", TemporaryLimitData::isFictitious, false) - .strings("group_name", TemporaryLimitData::getGroupId, false) - .booleans("selected", TemporaryLimitData::isSelected, false) .build(); } @@ -1295,59 +1233,5 @@ private static Stream, String>> getAliasesData(Network netw .map(alias -> Pair.of(identifiable, alias))); } - private static NetworkDataframeMapper areaVoltageLevels() { - return NetworkDataframeMapperBuilder.ofStream(NetworkDataframes::areaVoltageLevelsData) - .stringsIndex("id", pair -> pair.getLeft().getId()) - .strings("voltage_level_id", pair -> pair.getRight().getId()) - .build(); - } - - private static Stream> areaVoltageLevelsData(Network network) { - return network.getAreaStream() - .flatMap(area -> area.getVoltageLevelStream() - .map(voltageLevel -> Pair.of(area, voltageLevel))); - } - - private static NetworkDataframeMapper areaBoundaries() { - return NetworkDataframeMapperBuilder.ofStream(NetworkDataframes::areaBoundariesData) - .stringsIndex("id", pair -> pair.getLeft().getId()) - .strings("boundary_type", pair -> getAreaBoundaryType(pair.getRight()), false) - .strings("element", pair -> getAreaBoundaryElement(pair.getRight())) - .strings("side", pair -> getAreaBoundarySide(pair.getRight()), false) - .booleans("ac", pair -> pair.getRight().isAc()) - .doubles("p", (pair, context) -> perUnitPQ(context, pair.getRight().getP())) - .doubles("q", (pair, context) -> perUnitPQ(context, pair.getRight().getQ())) - .build(); - } - - private static String getAreaBoundaryType(AreaBoundary areaBoundary) { - Objects.requireNonNull(areaBoundary); - return areaBoundary.getBoundary().map( - b -> PyPowsyblApiHeader.ElementType.DANGLING_LINE.name() - ).orElse(PyPowsyblApiHeader.ElementType.TERMINAL.name()); - } - - private static String getAreaBoundaryElement(AreaBoundary areaBoundary) { - Objects.requireNonNull(areaBoundary); - return areaBoundary.getBoundary().map( - b -> b.getDanglingLine().getId() - ).orElseGet(() -> areaBoundary.getTerminal().orElseThrow().getConnectable().getId()); - } - - private static String getAreaBoundarySide(AreaBoundary areaBoundary) { - Objects.requireNonNull(areaBoundary); - if (areaBoundary.getBoundary().isPresent()) { - return ""; - } - Terminal terminal = areaBoundary.getTerminal().orElseThrow(); - return getTerminalSideStr(terminal.getConnectable(), terminal); - } - - private static Stream> areaBoundariesData(Network network) { - return network.getAreaStream() - .flatMap(area -> area.getAreaBoundaryStream() - .map(areaBoundary -> Pair.of(area, areaBoundary))); - } - } diff --git a/java/src/main/java/com/powsybl/dataframe/network/adders/DanglingLineDataframeAdder.java b/java/src/main/java/com/powsybl/dataframe/network/adders/DanglingLineDataframeAdder.java index 15bfb39ce..1ce93684c 100644 --- a/java/src/main/java/com/powsybl/dataframe/network/adders/DanglingLineDataframeAdder.java +++ b/java/src/main/java/com/powsybl/dataframe/network/adders/DanglingLineDataframeAdder.java @@ -109,11 +109,27 @@ Optional createAdder(Network network, int row, boolean throwE applyIfPresent(g, row, adder::setG); applyIfPresent(b, row, adder::setB); applyIfPresent(pairingKey, row, adder::setPairingKey); + addGenerationIfPresent(adder, row); return Optional.of(adder); } else { return Optional.empty(); } } + + private void addGenerationIfPresent(DanglingLineAdder adder, int row) { + if (minP == null && maxP == null && targetV == null && targetP == null && targetQ == null + && voltageRegulatorOn == null) { + return; + } + DanglingLineAdder.GenerationAdder genAdder = adder.newGeneration(); + applyIfPresent(minP, row, genAdder::setMinP); + applyIfPresent(maxP, row, genAdder::setMaxP); + applyIfPresent(targetP, row, genAdder::setTargetP); + applyIfPresent(targetQ, row, genAdder::setTargetQ); + applyIfPresent(targetV, row, genAdder::setTargetV); + applyBooleanIfPresent(voltageRegulatorOn, row, genAdder::setVoltageRegulationOn); + genAdder.add(); + } } @Override diff --git a/pypowsybl/_pypowsybl.pyi b/pypowsybl/_pypowsybl.pyi index 7343cce72..864fd59c6 100644 --- a/pypowsybl/_pypowsybl.pyi +++ b/pypowsybl/_pypowsybl.pyi @@ -143,7 +143,6 @@ class ElementType: BUS_FROM_BUS_BREAKER_VIEW: ClassVar[ElementType] = ... BUSBAR_SECTION: ClassVar[ElementType] = ... DANGLING_LINE: ClassVar[ElementType] = ... - DANGLING_LINE_GENERATION: ClassVar[ElementType] = ... TIE_LINE: ClassVar[ElementType] = ... GENERATOR: ClassVar[ElementType] = ... HVDC_LINE: ClassVar[ElementType] = ... diff --git a/pypowsybl/network/impl/network.py b/pypowsybl/network/impl/network.py index ae876a4e5..4af84f979 100644 --- a/pypowsybl/network/impl/network.py +++ b/pypowsybl/network/impl/network.py @@ -1244,6 +1244,12 @@ def get_dangling_lines(self, all_attributes: bool = False, attributes: List[str] - **ucte-xnode-code**: deprecated for pairing key. - **paired**: if the dangling line is paired with a tie line - **tie_line_id**: the ID of the tie line if the dangling line is paired + - **min_p** (optional): Minimum active power output of the dangling line's generation part + - **max_p** (optional): Maximum active power output of the dangling line's generation part + - **target_p** (optional): Active power target of the generation part + - **target_q** (optional): Reactive power target of the generation part + - **target_v** (optional): Voltage target of the generation part + - **voltage_regulator_on** (optional): ``True`` if the generation part regulates voltage This dataframe is indexed by the id of the dangling lines @@ -1293,35 +1299,6 @@ def get_dangling_lines(self, all_attributes: bool = False, attributes: List[str] """ return self.get_elements(ElementType.DANGLING_LINE, all_attributes, attributes, **kwargs) - def get_dangling_lines_generation(self, all_attributes: bool = False, attributes: List[str] = None, - **kwargs: ArrayLike): - r""" - Get a dataframe of the optional generation part of dangling lines. - - Args: - all_attributes: flag for including all attributes in the dataframe, default is false - attributes: attributes to include in the dataframe. The 2 parameters are mutually exclusive. - If no parameter is specified, the dataframe will include the default attributes. - kwargs: the data to be selected, as named arguments. - - Returns: - A dataframe of the generation part of the network dangling lines. - - Notes: - The resulting dataframe, depending on the parameters, will include the following columns: - - - **dangling_line_id**: The ID of the dangling line - - **target_p**: - - **voltage_regulator_on**: - - **target_q**: - - **target_v**: - - **min_p**: - - **max_p**: - - This dataframe is indexed by the id of the dangling lines to which the generation part is attached - """ - return self.get_elements(ElementType.DANGLING_LINE_GENERATION, all_attributes, attributes, **kwargs) - def get_tie_lines(self, all_attributes: bool = False, attributes: List[str] = None, **kwargs: ArrayLike) -> DataFrame: r""" @@ -4022,39 +3999,6 @@ def create_dangling_lines(self, df: DataFrame = None, **kwargs: ArrayLike) -> No kwargs.pop(ucte_xnode_code_str) return self._create_elements(ElementType.DANGLING_LINE, [df], **kwargs) - def create_dangling_line_generation_parts(self, df: Dataframe = None, **kwargs: ArrayLike): - """ - Creates the generation part of already created dangling lines. - - Args: - df: Attributes as a dataframe. - kwargs: Attributes as keyword arguments. - - Notes: - - Data may be provided as a dataframe or as keyword arguments. - In the latter case, all arguments must have the same length. - - Valid attributes are: - - - **dangling_line_id**: the identifier of the already existing dangling line - - **target_p**: - - **voltage_regulator_on**: - - **target_q**: - - **target_v**: - - **min_p**: - - **max_p**: - - Examples: - Using keyword arguments: - - .. code-block:: python - - network.create_dangling_line_generation_parts(id='BAT-1', voltage_level_id='VL1', bus_id='B1', - p0=10, q0=3, r=0, x=5, g=0, b=1e-6) - """ - return self._create_elements(ElementType.DANGLING_LINE_GENERATION, [df], **kwargs) - def create_lcc_converter_stations(self, df: DataFrame = None, **kwargs: ArrayLike) -> None: """ Creates LCC converter stations. diff --git a/tests/test_network.py b/tests/test_network.py index fd26d284c..c5beda151 100644 --- a/tests/test_network.py +++ b/tests/test_network.py @@ -1218,6 +1218,35 @@ def test_dangling_lines(): pd.testing.assert_frame_equal(expected, dangling_lines, check_dtype=False, atol=1e-2) +def test_dangling_line_generation(): + n = util.create_dangling_lines_network() + df = n.get_dangling_lines(attributes=['min_p', 'max_p', 'target_p', 'target_q', 'target_v', + 'voltage_regulator_on']) + assert not df['voltage_regulator_on']['DL'] + assert math.isnan(df['min_p']['DL']) + + with pytest.raises(PyPowsyblError) as context: + n.create_dangling_lines(id='DL2_wrong', voltage_level_id='VL', bus_id='BUS', + p0=100, q0=100, r=0, x=0, g=0, b=0, + target_v=100, voltage_regulator_on=True) + assert "invalid value (NaN) for active power setpoint" in str(context) + + n.create_dangling_lines(id='DL2', voltage_level_id='VL', bus_id='BUS', + p0=100, q0=100, r=0, x=0, g=0, b=0, + min_p=0, max_p=100, target_p=100, target_v=100, voltage_regulator_on=True) + df2 = n.get_dangling_lines(attributes=['min_p', 'max_p', 'target_p', 'target_q', 'target_v', + 'voltage_regulator_on']) + assert df2['voltage_regulator_on']['DL2'] + assert math.isnan(df2['target_q']['DL2']) + + n.update_dangling_lines(pd.DataFrame(index=['DL2'], columns=['target_q', 'voltage_regulator_on'], + data=[[100, False]])) + df3 = n.get_dangling_lines(attributes=['min_p', 'max_p', 'target_p', 'target_q', 'target_v', + 'voltage_regulator_on']) + assert not df3['voltage_regulator_on']['DL2'] + assert df3['target_q']['DL2']==100 + + def test_batteries(): n = util.create_battery_network() df = n.get_batteries(all_attributes=True)