diff --git a/src/GridCalEngine/Devices/Branches/tap_changer.py b/src/GridCalEngine/Devices/Branches/tap_changer.py index a633a628b..26a086e56 100644 --- a/src/GridCalEngine/Devices/Branches/tap_changer.py +++ b/src/GridCalEngine/Devices/Branches/tap_changer.py @@ -331,13 +331,14 @@ def init_from_cgmes(self, """ Import TapChanger object from CGMES - :param asymmetry_angle: :param low: :param high: :param normal: :param neutral: :param stepVoltageIncrement: :param step: + :param asymmetry_angle: + :param tc_type: :return: """ @@ -345,7 +346,7 @@ def init_from_cgmes(self, if self._negative_low: self.asymmetry_angle = float(asymmetry_angle) # assymetry angle (Theta) - self._total_positions = int(high-low) # total number of positions + self._total_positions = int(high-low+1) # total number of positions self.dV = float(stepVoltageIncrement / 100) # voltage increment in p.u. self.neutral_position = int(neutral - low + 1) # neutral position self.normal_position = int(normal - low + 1) # normal position @@ -354,7 +355,7 @@ def init_from_cgmes(self, else: self.asymmetry_angle = float(asymmetry_angle) # assymetry angle (Theta) - self._total_positions = int(high-low) # total number of positions + self._total_positions = int(high-low+1) # total number of positions self.dV = float(stepVoltageIncrement / 100) # voltage increment in p.u. self.neutral_position = int(neutral) # neutral position self.normal_position = int(normal) # normal position @@ -377,14 +378,14 @@ def get_cgmes_values(self): if self._negative_low: low = -self.neutral_position + 1 - high = self.total_positions - self.neutral_position + 1 + high = self.total_positions - self.neutral_position normal = self.normal_position + low - 1 neutral = self.neutral_position + low - 1 sVI = self.dV * 100 step = self.tap_position + low - 1 else: low = 0 - high = self.total_positions + high = self.total_positions-1 normal = self.normal_position neutral = self.neutral_position sVI = self.dV * 100 diff --git a/src/GridCalEngine/Devices/Branches/transformer3w.py b/src/GridCalEngine/Devices/Branches/transformer3w.py index ceeb58158..5801b1185 100644 --- a/src/GridCalEngine/Devices/Branches/transformer3w.py +++ b/src/GridCalEngine/Devices/Branches/transformer3w.py @@ -49,6 +49,9 @@ def __init__(self, idtag: Union[str, None] = None, name: str = 'Branch', bus0: Union[None, Bus] = None, bus1: Bus = None, bus2: Bus = None, bus3: Bus = None, + w1_idtag: Union[str, None] = None, + w2_idtag: Union[str, None] = None, + w3_idtag: Union[str, None] = None, V1=10.0, V2=10.0, V3=10.0, active=True, r12=0.0, r23=0.0, r31=0.0, x12=0.0, x23=0.0, x31=0.0, rate12=0.0, rate23=0.0, rate31=0.0, @@ -113,9 +116,9 @@ def __init__(self, idtag: Union[str, None] = None, self._rate23 = float(rate23) self._rate31 = float(rate31) - self.winding1 = Winding(bus_from=self.bus0, bus_to=bus1, HV=V1, LV=1.0, name=name + "_W1") - self.winding2 = Winding(bus_from=self.bus0, bus_to=bus2, HV=V2, LV=1.0, name=name + "_W2") - self.winding3 = Winding(bus_from=self.bus0, bus_to=bus3, HV=V3, LV=1.0, name=name + "_W3") + self.winding1 = Winding(bus_from=self.bus0, idtag=w1_idtag, bus_to=bus1, HV=V1, LV=1.0, name=name + "_W1") + self.winding2 = Winding(bus_from=self.bus0, idtag=w2_idtag, bus_to=bus2, HV=V2, LV=1.0, name=name + "_W2") + self.winding3 = Winding(bus_from=self.bus0, idtag=w3_idtag, bus_to=bus3, HV=V3, LV=1.0, name=name + "_W3") self.x = float(x) self.y = float(y) diff --git a/src/GridCalEngine/IO/cim/cgmes/cgmes_to_gridcal.py b/src/GridCalEngine/IO/cim/cgmes/cgmes_to_gridcal.py index fbdab99ef..f2b48b24e 100644 --- a/src/GridCalEngine/IO/cim/cgmes/cgmes_to_gridcal.py +++ b/src/GridCalEngine/IO/cim/cgmes/cgmes_to_gridcal.py @@ -713,42 +713,93 @@ def get_gcdev_ac_lines(cgmes_model: CgmesCircuit, expected_value=2) -def get_tap_changer_values(windings): - """ - Get Tap Changer values from one of the given windings (that is not None). - - :param windings: List of transformer windings. - :return: - """ - tap_module: float = 1.0 - total_positions, neutral_pos, normal, tap_step, dV = 0, 0, 0, 0, 0.0 - tc_type = TapChangerTypes.NoRegulation - - for winding in windings: - rtc = winding.RatioTapChanger - if rtc is not None: - total_positions = rtc.highStep - rtc.lowStep + 1 # lowStep generally negative - neutral_pos = rtc.neutralStep - rtc.lowStep - normal = rtc.normalStep - rtc.lowStep - dV = round(rtc.stepVoltageIncrement / 100, 6) - # tc._tap_position = neutral_position # index with respect to the neutral position = Step from SSH - # set after initialisation - tap_step = rtc.step - tap_module = round(1 + (rtc.step - rtc.neutralStep) * dV, 6) - - # Control from Control object - if (getattr(rtc, 'TapChangerControl', None) and - rtc.TapChangerControl.mode == cgmes_enums.RegulatingControlModeKind.voltage): - tc_type = TapChangerTypes.VoltageRegulation - - # tculControlMode is not relevant - # if (hasattr(rtc, 'tculControlMode') and - # rtc.tculControlMode == cgmes_enums.TransformerControlMode.volt): - # tc_type = TapChangerTypes.VoltageRegulation +# def get_tap_changer_values(windings): +# """ +# Get Tap Changer values from one of the given windings (that is not None). +# +# :param windings: List of transformer windings. +# :return: +# """ +# tap_module: float = 1.0 +# total_positions, neutral_pos, normal, tap_step, dV = 0, 0, 0, 0, 0.0 +# tc_type = TapChangerTypes.NoRegulation +# +# for winding in windings: +# rtc = winding.RatioTapChanger +# if rtc is not None: +# total_positions = rtc.highStep - rtc.lowStep + 1 # lowStep generally negative +# neutral_pos = rtc.neutralStep - rtc.lowStep +# normal = rtc.normalStep - rtc.lowStep +# dV = round(rtc.stepVoltageIncrement / 100, 6) +# # tc._tap_position = neutral_position # index with respect to the neutral position = Step from SSH +# # set after initialisation +# tap_step = rtc.step +# tap_module = round(1 + (rtc.step - rtc.neutralStep) * dV, 6) +# +# # Control from Control object +# if (getattr(rtc, 'TapChangerControl', None) and +# rtc.TapChangerControl.mode == cgmes_enums.RegulatingControlModeKind.voltage): +# tc_type = TapChangerTypes.VoltageRegulation +# +# # tculControlMode is not relevant +# # if (hasattr(rtc, 'tculControlMode') and +# # rtc.tculControlMode == cgmes_enums.TransformerControlMode.volt): +# # tc_type = TapChangerTypes.VoltageRegulation +# +# else: +# continue +# return tap_module, total_positions, neutral_pos, normal, dV, tc_type, tap_step - else: - continue - return tap_module, total_positions, neutral_pos, normal, dV, tc_type, tap_step +# +# def set_tap_changer_values(windings, +# gcdev_trafo: gcdev.Transformer2W) -> None: +# """ +# Get Tap Changer values from one of the given windings (that is not None). +# +# :param gcdev_trafo: GridCal transformer +# :param windings: List of transformer windings. +# :return: +# """ +# total_positions, neutral_pos, normal, tap_step, dV = 0, 0, 0, 0, 0.0 +# tc_type = TapChangerTypes.NoRegulation +# +# for winding in windings: +# rtc = winding.RatioTapChanger +# if rtc is not None: +# # Control from Control object +# if (getattr(rtc, 'TapChangerControl', None) and +# rtc.TapChangerControl.mode == cgmes_enums.RegulatingControlModeKind.voltage): +# tc_type = TapChangerTypes.VoltageRegulation +# +# gcdev_trafo.tap_changer.init_from_cgmes( +# low=rtc.lowStep, +# high=rtc.highStep, +# normal=rtc.normalStep, +# neutral=rtc.neutralStep, +# stepVoltageIncrement=rtc.stepVoltageIncrement, +# step=rtc.step, +# asymmetry_angle=90, +# tc_type=tc_type) +# +# ptc = winding.PhaseTapChanger +# # if isinstance(ptc, cgmes_model.get_class_type("PhaseTapChangerSymmetrical")): +# if ptc is not None: +# # Control from Control object +# if (getattr(ptc, 'TapChangerControl', None) and +# ptc.TapChangerControl.mode == cgmes_enums.RegulatingControlModeKind.voltage): +# tc_type = TapChangerTypes.VoltageRegulation +# +# gcdev_trafo.tap_changer.init_from_cgmes( +# low=ptc.lowStep, +# high=ptc.highStep, +# normal=ptc.normalStep, +# neutral=ptc.neutralStep, +# stepVoltageIncrement=ptc.voltageStepIncrement, +# step=ptc.step, +# asymmetry_angle=90, +# tc_type=tc_type) +# +# return def get_gcdev_ac_transformers(cgmes_model: CgmesCircuit, @@ -813,8 +864,6 @@ def get_gcdev_ac_transformers(cgmes_model: CgmesCircuit, # get per unit values r, x, g, b, r0, x0, g0, b0 = get_pu_values_power_transformer(cgmes_elm, Sbase) rated_s = windings[0].ratedS - # get Tap data - tap_m, total_pos, neutral_pos, normal_pos, dV, tc_type, tap_pos = get_tap_changer_values(windings) gcdev_elm = gcdev.Transformer2W(idtag=cgmes_elm.uuid, code=cgmes_elm.description, @@ -835,22 +884,24 @@ def get_gcdev_ac_transformers(cgmes_model: CgmesCircuit, x0=x0, g0=g0, b0=b0, - tap_module=tap_m, - # tap_phase=0.0, - # tap_module_control_mode=, # leave fixed - # tap_angle_control_mode=, - tc_total_positions=total_pos, - tc_neutral_position=neutral_pos, - tc_normal_position=normal_pos, - tc_dV=dV, - # tc_asymmetry_angle = 90, - tc_type=tc_type, + # tap_module=tap_m, + # # tap_phase=0.0, + # # tap_module_control_mode=, # leave fixed + # # tap_angle_control_mode=, + # tc_total_positions=total_pos, + # tc_neutral_position=neutral_pos, + # tc_normal_position=normal_pos, + # tc_dV=dV, + # # tc_asymmetry_angle = 90, + # tc_type=tc_type, rate=rate_mva) - # TAP Changer INIT from CGMES - gcdev_elm.tap_changer.tap_position = tap_pos - print(f'Tap_module is {gcdev_elm.tap_changer.get_tap_module()} , {tap_m}') - # TODO add highest step, plus attr needed + # # get Tap data from CGMES + # tap_m, total_pos, neutral_pos, normal_pos, dV, tc_type, tap_pos = get_tap_changer_values(windings) + + # # TAP Changer INIT from CGMES + # set_tap_changer_values(windings=windings, + # gcdev_trafo=gcdev_elm) gcdev_model.add_transformer2w(gcdev_elm) else: @@ -896,6 +947,9 @@ def get_gcdev_ac_transformers(cgmes_model: CgmesCircuit, bus1=calc_node_1, bus2=calc_node_2, bus3=calc_node_3, + w1_idtag=windings[0].uuid, + w2_idtag=windings[1].uuid, + w3_idtag=windings[2].uuid, V1=v1, V2=v2, V3=v3, @@ -966,6 +1020,124 @@ def get_gcdev_ac_transformers(cgmes_model: CgmesCircuit, expected_value=2) +def get_transformer_tap_changers(cgmes_model: CgmesCircuit, + gcdev_model: MultiCircuit, + logger: DataLogger) -> None: + """ + Process Tap Changer Classes from CGMES and put them into GridCal transformers. + + :param cgmes_model: + :param gcdev_model: + :param logger: + :return: + """ + # Ratio Tap Changer + for ratio_tc in cgmes_model.cgmes_assets.RatioTapChanger_list: + trafo_id = ratio_tc.TransformerEnd.PowerTransformer.uuid + + gcdev_trafo = find_object_by_idtag( + object_list=gcdev_model.transformers2w + gcdev_model.transformers3w, + target_idtag=trafo_id + ) + + # Control from Control object + if (getattr(ratio_tc, 'TapChangerControl', None) and + ratio_tc.TapChangerControl.mode == cgmes_enums.RegulatingControlModeKind.voltage): + tc_type = TapChangerTypes.VoltageRegulation + else: + tc_type = TapChangerTypes.NoRegulation + + if isinstance(gcdev_trafo, gcdev.Transformer2W): + + gcdev_trafo.tap_changer.init_from_cgmes( + low=ratio_tc.lowStep, + high=ratio_tc.highStep, + normal=ratio_tc.normalStep, + neutral=ratio_tc.neutralStep, + stepVoltageIncrement=ratio_tc.stepVoltageIncrement, + step=int(ratio_tc.step), + # asymmetry_angle=90, + tc_type=tc_type + ) + + # SET tap_module and tap_phase from its own TapChanger object + gcdev_trafo.tap_module = gcdev_trafo.tap_changer.get_tap_module() + # gcdev_trafo.tap_phase = gcdev_trafo.tap_changer.get_tap_phase() + + elif isinstance(gcdev_trafo, gcdev.Transformer3W): + winding_id = ratio_tc.TransformerEnd.uuid + # get the winding with the TapChanger + winding_w_tc = find_object_by_idtag( + object_list=[gcdev_trafo.winding1, + gcdev_trafo.winding2, + gcdev_trafo.winding3], + target_idtag=winding_id + ) + + winding_w_tc.tap_changer.init_from_cgmes( + low=ratio_tc.lowStep, + high=ratio_tc.highStep, + normal=ratio_tc.normalStep, + neutral=ratio_tc.neutralStep, + stepVoltageIncrement=ratio_tc.stepVoltageIncrement, + step=int(ratio_tc.step), + # asymmetry_angle=90, + tc_type=tc_type + ) + + # SET tap_module and tap_phase from its own TapChanger object + winding_w_tc.tap_module = winding_w_tc.tap_changer.get_tap_module() + # gcdev_trafo.tap_phase = gcdev_trafo.tap_changer.get_tap_phase() + + else: + logger.add_error(msg='Transformer not found for RatioTapChanger', + device=ratio_tc.rdfid, + device_class=ratio_tc.tpe, + device_property="transformer for powertransformerend", + value=None, + expected_value=trafo_id) + + + # # PHASE + # for phase_tc_s in cgmes_model.cgmes_assets.PhaseTapChangerSymmetrical_list: + # trafo_id = phase_tc_s.TransformerEnd.PowerTransformer.uuid + # + # gcdev_trafo = find_object_by_idtag( + # object_list=gcdev_model.transformers2w, + # target_idtag=trafo_id + # ) + # if isinstance(gcdev_trafo, gcdev.Transformer2W): + # + # gcdev_trafo.tap_changer.init_from_cgmes( + # low=phase_tc_s.lowStep, + # high=phase_tc_s.highStep, + # normal=phase_tc_s.normalStep, + # neutral=phase_tc_s.neutralStep, + # stepVoltageIncrement=phase_tc_s.stepVoltageIncrement, + # step=phase_tc_s.step, + # # asymmetry_angle=90, + # ) + # + # # Control from Control object + # if (getattr(phase_tc_s, 'TapChangerControl', None) and + # phase_tc_s.TapChangerControl.mode == cgmes_enums.RegulatingControlModeKind.voltage): + # gcdev_trafo.tap_changer.tc_type = TapChangerTypes.VoltageRegulation + # + # else: + # logger.add_error( + # msg='Transformer not found for RatioTapChanger', + # device=phase_tc_s.rdfid, + # device_class=phase_tc_s.tpe, + # device_property="transformer for powertransformerend", + # value=None, + # expected_value=trafo_id) + # + # # SET tap_module and tap_phase from its own TapChanger object + # gcdev_trafo.tap_module = gcdev_trafo.tap_changer.get_tap_module() + # gcdev_trafo.tap_phase = gcdev_trafo.tap_changer.get_tap_phase() + + + def get_gcdev_shunts(cgmes_model: CgmesCircuit, gcdev_model: MultiCircuit, calc_node_dict: Dict[str, gcdev.Bus], @@ -1454,6 +1626,9 @@ def cgmes_to_gridcal(cgmes_model: CgmesCircuit, device_to_terminal_dict=device_to_terminal_dict, logger=logger, Sbase=Sbase) + get_transformer_tap_changers(cgmes_model=cgmes_model, + gcdev_model=gc_model, + logger=logger) get_gcdev_shunts(cgmes_model=cgmes_model, gcdev_model=gc_model, @@ -1476,21 +1651,9 @@ def cgmes_to_gridcal(cgmes_model: CgmesCircuit, cgmes_model.emit_progress(100) cgmes_model.emit_text("Cgmes import done!") - # Gridcal to cgmes - # cgmes_model_export = CgmesCircuit( - # cgmes_version=cgmes_model.options.cgmes_version.__str__(), - # text_func=cgmes_model.text_func, - # progress_func=cgmes_model.progress_func, logger=logger) - # cgmes_model_export = gridcal_to_cgmes(gc_model, cgmes_model_export, None, logger) - - # Export test for the imported data - # start = time.time() - # serializer = CimExporter(cgmes_model_export) - # serializer.export_test() - # end = time.time() - # print("ET export time: ", end - start, "sec") - - # Export data converted from gridcal + import os + print(os.getcwd()) + cgmes_model.to_excel(fname="cgmes_circuit.xlsx") # Run topology progcessing # tp_info = gc_model.process_topology_at() diff --git a/src/GridCalEngine/IO/cim/cgmes/gridcal_to_cgmes.py b/src/GridCalEngine/IO/cim/cgmes/gridcal_to_cgmes.py index 670d9a7af..f18dd33e8 100644 --- a/src/GridCalEngine/IO/cim/cgmes/gridcal_to_cgmes.py +++ b/src/GridCalEngine/IO/cim/cgmes/gridcal_to_cgmes.py @@ -1002,6 +1002,7 @@ def get_cgmes_power_transformers(multicircuit_model: MultiCircuit, cgmes_model: CgmesCircuit, logger: DataLogger): """ + Creates all transformer related CGMES classes from GridCal transformer. :param multicircuit_model: :param cgmes_model: @@ -1098,7 +1099,8 @@ def get_cgmes_power_transformers(multicircuit_model: MultiCircuit, pte2.ratedS = mc_elm.Sn pte2.endNumber = 2 - # ----------------------------------------------------------------- + # TODO -------------------- PHASE TAP ------------------------------ + # -------------------- RATIO TAP ------------------------------ # TAP Changer EQ new_rdf_id = get_new_rdfid() object_template = cgmes_model.get_class_type("RatioTapChanger") @@ -1118,19 +1120,6 @@ def get_cgmes_power_transformers(multicircuit_model: MultiCircuit, tap_changer.stepVoltageIncrement, tap_changer.step) = mc_elm.tap_changer.get_cgmes_values() - # tap_changer.lowStep = mc_elm.tap_changer.get_tap_low_step() - # tap_changer.highStep = mc_elm.tap_changer.get_tap_high_step() - # tap_changer.neutralStep = mc_elm.tap_changer.neutral_position + tap_changer.lowStep - # tap_changer.normalStep = mc_elm.tap_changer.normal_position + tap_changer.lowStep - - # Tap step increment, in per cent of nominal voltage, per step position. - # if mc_elm.tap_changer.tap_position == mc_elm.tap_changer.neutral_position: - # tap_changer.stepVoltageIncrement = 0 - # else: - # tap_changer.stepVoltageIncrement = ( - # (mc_elm.tap_module - 1) / (mc_elm.tap_changer.tap_position - mc_elm.tap_changer.neutral_position) - # ) - # CONTROL tap_changer.ltcFlag = False # load tap changing capability tap_changer.TapChangerControl = create_cgmes_tap_changer_control( @@ -1141,9 +1130,7 @@ def get_cgmes_power_transformers(multicircuit_model: MultiCircuit, ) # tculControlMode not used, but be set to something: volt/react .. tap_changer.tculControlMode = TransformerControlMode.volt - # TAP Changer SSH - tap_changer.step = mc_elm.tap_changer.tap_position tap_changer.controlEnabled = False # Specifies the regulation status of the equipment. True is regulating, false is not regulating. # why, why not? @@ -1442,19 +1429,20 @@ def get_cgmes_topological_island(multicircuit_model: MultiCircuit, mc_bus = find_object_by_attribute(multicircuit_model.buses, "name", tn_name) mc_buses.append(mc_bus) - slack_bus = find_object_by_attribute(mc_buses, "is_slack", True) - if slack_bus: - slack_tn = find_object_by_uuid(cgmes_model, - cgmes_model.cgmes_assets.TopologicalNode_list, - slack_bus.idtag) - new_island.AngleRefTopologicalNode = slack_tn - for tn in new_island.TopologicalNodes: - tn.AngleRefTopologicalIsland = slack_tn - else: - logger.add_warning( - msg="AngleRefTopologicalNode missing from TopologicalIsland!", - device=new_island.name, - device_property="AngleRefTopologicalNode") + if mc_buses: + slack_bus = find_object_by_attribute(mc_buses, "is_slack", True) + if slack_bus: + slack_tn = find_object_by_uuid(cgmes_model, + cgmes_model.cgmes_assets.TopologicalNode_list, + slack_bus.idtag) + new_island.AngleRefTopologicalNode = slack_tn + for tn in new_island.TopologicalNodes: + tn.AngleRefTopologicalIsland = slack_tn + else: + logger.add_warning( + msg="AngleRefTopologicalNode missing from TopologicalIsland!", + device=new_island.name, + device_property="AngleRefTopologicalNode") cgmes_model.add(new_island) diff --git a/src/GridCalEngine/IO/raw/raw_to_gridcal.py b/src/GridCalEngine/IO/raw/raw_to_gridcal.py index ba609074a..4d07be5e3 100644 --- a/src/GridCalEngine/IO/raw/raw_to_gridcal.py +++ b/src/GridCalEngine/IO/raw/raw_to_gridcal.py @@ -43,8 +43,8 @@ def get_gridcal_bus(psse_bus: RawBus, - area_dict: Dict[int, dev.Country], - zone_dict: Dict[int, dev.Community], + area_dict: Dict[int, dev.Area], + zone_dict: Dict[int, dev.Zone], logger: Logger) -> Tuple[dev.Bus, Union[dev.Shunt, None]]: """ @@ -60,8 +60,8 @@ def get_gridcal_bus(psse_bus: RawBus, bus = dev.Bus(name=name, Vnom=psse_bus.BASKV, code=str(psse_bus.I), vmin=psse_bus.EVLO, vmax=psse_bus.EVHI, xpos=0, ypos=0, active=True, - country=area_dict[psse_bus.AREA], - # zone=zone_dict[psse_bus.ZONE], + area=area_dict[psse_bus.AREA], + zone=zone_dict[psse_bus.ZONE], Vm0=psse_bus.VM, Va0=np.deg2rad(psse_bus.VA)) @@ -72,8 +72,8 @@ def get_gridcal_bus(psse_bus: RawBus, xpos=0, ypos=0, active=True, - country=area_dict[psse_bus.AREA], - # zone=zone_dict[psse_bus.ZONE], + area=area_dict[psse_bus.AREA], + zone=zone_dict[psse_bus.ZONE], Vm0=psse_bus.VM, Va0=np.deg2rad(psse_bus.VA)) @@ -82,8 +82,8 @@ def get_gridcal_bus(psse_bus: RawBus, name = psse_bus.NAME bus = dev.Bus(name=name, code=str(psse_bus.I), Vnom=psse_bus.BASKV, vmin=0.9, vmax=1.1, xpos=0, ypos=0, active=True, - country=area_dict[psse_bus.AREA], - # zone=zone_dict[psse_bus.ZONE], + area=area_dict[psse_bus.AREA], + zone=zone_dict[psse_bus.ZONE], Vm0=psse_bus.VM, Va0=np.deg2rad(psse_bus.VA)) @@ -99,8 +99,8 @@ def get_gridcal_bus(psse_bus: RawBus, bus = dev.Bus(name=name, Vnom=psse_bus.BASKV, code=str(psse_bus.I), vmin=psse_bus.EVLO, vmax=psse_bus.EVHI, xpos=0, ypos=0, active=True, - country=area_dict[psse_bus.AREA], - # zone=zone_dict[psse_bus.ZONE], + area=area_dict[psse_bus.AREA], + zone=zone_dict[psse_bus.ZONE], Vm0=psse_bus.VM, Va0=np.deg2rad(psse_bus.VA)) @@ -767,11 +767,11 @@ def psse_to_gridcal(psse_circuit: PsseCircuit, circuit = MultiCircuit(Sbase=psse_circuit.SBASE) circuit.comments = 'Converted from a PSS/e .raw file' - circuit.countries = [dev.Country(name=x.ARNAME) for x in psse_circuit.areas] - circuit.communities = [dev.Community(name=x.ZONAME) for x in psse_circuit.zones] + circuit.areas = [dev.Area(name=x.ARNAME) for x in psse_circuit.areas] + circuit.zones = [dev.Zone(name=x.ZONAME) for x in psse_circuit.zones] - area_dict = {val.I: elm for val, elm in zip(psse_circuit.areas, circuit.countries)} - zones_dict = {val.I: elm for val, elm in zip(psse_circuit.zones, circuit.communities)} + area_dict = {val.I: elm for val, elm in zip(psse_circuit.areas, circuit.areas)} + zones_dict = {val.I: elm for val, elm in zip(psse_circuit.zones, circuit.zones)} # scan for missing zones or areas (yes, PSSe is so crappy that can reference areas that do not exist) missing_areas = False @@ -807,10 +807,10 @@ def psse_to_gridcal(psse_circuit: PsseCircuit, circuit.add_shunt(bus=bus, api_obj=bus_shunt) if missing_areas: - circuit.countries = [v for k, v in area_dict.items()] + circuit.areas = [v for k, v in area_dict.items()] if missing_zones: - circuit.communities = [v for k, v in zones_dict.items()] + circuit.zones = [v for k, v in zones_dict.items()] # check htat the area slack buses actually make sense for area in psse_circuit.areas: diff --git a/src/tests/test_cgmes_roundtrip.py b/src/tests/test_cgmes_roundtrip.py index 196331f74..af2368f44 100644 --- a/src/tests/test_cgmes_roundtrip.py +++ b/src/tests/test_cgmes_roundtrip.py @@ -120,6 +120,7 @@ def test_cgmes_roundtrip(): :return: """ test_grid_name = 'micro_grid_NL_T1.zip' + # test_grid_name = 'micro_grid_assmb_base.zip' boundary_set_name = 'micro_grid_BD.zip' # test_grid_name = 'IEEE 14 bus.zip' diff --git a/src/trunk/controls/scripts/tap_changer_steps_2.py b/src/trunk/controls/scripts/tap_changer_steps_2.py new file mode 100644 index 000000000..89f2c06c1 --- /dev/null +++ b/src/trunk/controls/scripts/tap_changer_steps_2.py @@ -0,0 +1,47 @@ +import pandas as pd +import numpy as np +import GridCalEngine.api as gci + +# CGMES data 1 +low = -20 +high = 20 +normal = -2 +neutral = 0 +sVI = 0.8 +step = -2 +# # CGMES data 2 +# low = 0 +# high = 33 +# normal = 17 +# neutral = 17 +# sVI = 0.625 +# step = 17 + +tap_changer = gci.TapChanger() +tap_changer.init_from_cgmes( + low=low, + high=high, + normal=normal, + neutral=neutral, + stepVoltageIncrement=sVI, + step=step +) +print(tap_changer.total_positions, tap_changer.tap_position) +print(f'{tap_changer.get_cgmes_values()}') + +low_2, high_2, normal_2, neutral_2, sVI_2, step_2 = tap_changer.get_cgmes_values() + +# df = pd.DataFrame(data={'idx': np.arange(len(tap_changer._m_array)), +# 'm': tap_changer._m_array, +# 'tau': tap_changer._tau_array +# }) +# +# print(tap_changer.get_tap_module()) +# print(df) + +assert low == low_2 +assert high == high_2 +assert normal == normal_2 +assert neutral == neutral_2 +assert sVI == sVI_2 +assert step == step_2