From 139193a9c84ad15e342f632ac29afac909802b78 Mon Sep 17 00:00:00 2001 From: Changgang Li Date: Wed, 13 Apr 2022 21:08:17 +0800 Subject: [PATCH] v1.6.0. Release with tested VSC HVDC model. stepspy also updated. --- README.md | 3 +- python/stepspy-current/setup.py | 2 +- .../stepspy/libsteps/pylibsteps.py | 50 +++ python/stepspy-current/stepspy/stepspy.py | 421 +++++++++++++++++- 4 files changed, 471 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index 03e30244..baef2c4b 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ * STEPS: https://github.com/changgang/steps and https://gitee.com/lichgang/steps/ * stepspy: https://pypi.org/project/stepspy/ * Documentation: https://github.com/changgang/steps/wiki/ -- Date of Readme: Feb 2, 2022 +- Date of Readme: April 13, 2022 # Reference Please cite STEPS with the following paper: @@ -19,6 +19,7 @@ Though BPA dat format is supported, it will be supported in the future version i You are encouraged to join us for further development. ## Major versions +- v1.6.0. Add VSC HVDC for powerflow and dynamic simulation. stepspy also updated. Released on April 13, 2022. - v1.5.4. Update to improve performance. Released on Oct. 20, 2021. - v1.5.2. Add new APIs to get generator related model internal variables. Start to add linearization codes. Released on March. 24, 2021. - v1.5.1. Add new option export_full to functions of save_network_Y_matrix and APIs. stepspy is also updated. Start to add sequential parameters to STEPS. Released on Feb. 2, 2021. diff --git a/python/stepspy-current/setup.py b/python/stepspy-current/setup.py index 01b0bc4b..1e217cb4 100644 --- a/python/stepspy-current/setup.py +++ b/python/stepspy-current/setup.py @@ -5,7 +5,7 @@ setuptools.setup( name="stepspy", - version="1.5.3.1", + version="1.6.0", author="Changgang Li", author_email="lichgang@sdu.edu.cn", description="Python module of Simulation Toolkit for Electrical Power Systems", diff --git a/python/stepspy-current/stepspy/libsteps/pylibsteps.py b/python/stepspy-current/stepspy/libsteps/pylibsteps.py index aa44b9c7..170cad2c 100644 --- a/python/stepspy-current/stepspy/libsteps/pylibsteps.py +++ b/python/stepspy-current/stepspy/libsteps/pylibsteps.py @@ -109,6 +109,8 @@ def load_library(): libsteps.api_load_powerflow_data_from_file.restype = None libsteps.api_load_powerflow_data_from_file.argtypes = (c_char_p, c_char_p, c_uint) + libsteps.api_load_vsc_hvdc_powerflow_data_from_file.restype = None + libsteps.api_load_vsc_hvdc_powerflow_data_from_file.argtypes = (c_char_p, c_char_p, c_uint) libsteps.api_load_powerflow_result_from_file.restype = None libsteps.api_load_powerflow_result_from_file.argtypes = (c_char_p, c_char_p, c_uint) libsteps.api_load_dynamic_data_from_file.restype = None @@ -116,6 +118,8 @@ def load_library(): libsteps.api_save_powerflow_data_to_file.restype = None libsteps.api_save_powerflow_data_to_file.argtypes = (c_char_p, c_char_p, c_bool, c_bool, c_bool, c_uint, c_uint) + libsteps.api_save_vsc_hvdc_powerflow_data_to_file.restype = None + libsteps.api_save_vsc_hvdc_powerflow_data_to_file.argtypes = (c_char_p, c_char_p, c_bool, c_bool, c_bool, c_uint, c_uint) libsteps.api_save_dynamic_data_to_file.restype = None libsteps.api_save_dynamic_data_to_file.argtypes = (c_char_p, c_char_p, c_bool, c_uint) @@ -195,6 +199,8 @@ def load_library(): libsteps.api_is_transformer_exist.argtypes = (c_uint, c_uint, c_uint, c_char_p, c_uint) libsteps.api_is_hvdc_exist.restype = c_bool libsteps.api_is_hvdc_exist.argtypes = (c_uint, c_uint, c_char_p, c_uint) + libsteps.api_is_vsc_hvdc_exist.restype = c_bool + libsteps.api_is_vsc_hvdc_exist.argtypes = (c_char_p, c_uint) libsteps.api_is_equivalent_device_exist.restype = c_bool libsteps.api_is_equivalent_device_exist.argtypes = (c_uint, c_char_p, c_uint) @@ -274,6 +280,8 @@ def load_library(): libsteps.api_add_line.argtypes = (c_uint, c_uint, c_char_p, c_uint) libsteps.api_add_hvdc.restype = None libsteps.api_add_hvdc.argtypes = (c_uint, c_uint, c_char_p, c_uint) + libsteps.api_add_vsc_hvdc.restype = None + libsteps.api_add_vsc_hvdc.argtypes = (c_char_p, c_uint) libsteps.api_add_transformer.restype = None libsteps.api_add_transformer.argtypes = (c_uint, c_uint, c_uint, c_char_p, c_uint) libsteps.api_add_equivalent_device.restype = None @@ -303,6 +311,8 @@ def load_library(): libsteps.api_remove_line.argtypes = (c_uint, c_uint, c_char_p, c_uint) libsteps.api_remove_hvdc.restype = None libsteps.api_remove_hvdc.argtypes = (c_uint, c_uint, c_char_p, c_uint) + libsteps.api_remove_vsc_hvdc.restype = None + libsteps.api_remove_vsc_hvdc.argtypes = (c_char_p, c_uint) libsteps.api_remove_transformer.restype = None libsteps.api_remove_transformer.argtypes = (c_uint, c_uint, c_uint, c_char_p, c_uint) libsteps.api_remove_equivalent_device.restype = None @@ -436,6 +446,23 @@ def load_library(): libsteps.api_set_hvdc_boolean_data.restype = None libsteps.api_set_hvdc_boolean_data.argtypes = (c_uint, c_uint, c_char_p, c_char_p, c_char_p, c_bool, c_uint) + libsteps.api_get_vsc_hvdc_integer_data.restype = (c_int) + libsteps.api_get_vsc_hvdc_integer_data.argtypes = (c_char_p, c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_get_vsc_hvdc_float_data.restype = (c_double) + libsteps.api_get_vsc_hvdc_float_data.argtypes = (c_char_p, c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_get_vsc_hvdc_string_data.restype = (c_char_p) + libsteps.api_get_vsc_hvdc_string_data.argtypes = (c_char_p, c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_get_vsc_hvdc_boolean_data.restype = (c_bool) + libsteps.api_get_vsc_hvdc_boolean_data.argtypes = (c_char_p, c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_set_vsc_hvdc_integer_data.restype = None + libsteps.api_set_vsc_hvdc_integer_data.argtypes = (c_char_p, c_char_p, c_char_p, c_int, c_uint, c_uint) + libsteps.api_set_vsc_hvdc_float_data.restype = None + libsteps.api_set_vsc_hvdc_float_data.argtypes = (c_char_p, c_char_p, c_char_p, c_double, c_uint, c_uint) + libsteps.api_set_vsc_hvdc_string_data.restype = None + libsteps.api_set_vsc_hvdc_string_data.argtypes = (c_char_p, c_char_p, c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_set_vsc_hvdc_boolean_data.restype = None + libsteps.api_set_vsc_hvdc_boolean_data.argtypes = (c_char_p, c_char_p, c_char_p, c_bool, c_uint, c_uint) + libsteps.api_get_area_integer_data.restype = (c_int) libsteps.api_get_area_integer_data.argtypes = (c_uint, c_char_p, c_uint) libsteps.api_get_area_float_data.restype = (c_double) @@ -550,6 +577,16 @@ def load_library(): libsteps.api_get_hvdc_related_model_float_parameter_name.restype = c_char_p libsteps.api_get_hvdc_related_model_float_parameter_name.argtypes = (c_uint, c_uint, c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_get_vsc_hvdc_related_model_name.restype = c_char_p + libsteps.api_get_vsc_hvdc_related_model_name.argtypes = (c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_get_vsc_hvdc_related_model_float_parameter.restype = c_double + libsteps.api_get_vsc_hvdc_related_model_float_parameter.argtypes = (c_char_p, c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_set_vsc_hvdc_related_model_float_parameter.restype = None + libsteps.api_set_vsc_hvdc_related_model_float_parameter.argtypes = (c_char_p, c_char_p, c_char_p, c_double, c_uint, c_uint) + libsteps.api_get_vsc_hvdc_related_model_float_parameter_count.restype = c_uint + libsteps.api_get_vsc_hvdc_related_model_float_parameter_count.argtypes = (c_char_p, c_char_p, c_uint, c_uint) + libsteps.api_get_vsc_hvdc_related_model_float_parameter_name.restype = c_char_p + libsteps.api_get_vsc_hvdc_related_model_float_parameter_name.argtypes = (c_char_p, c_char_p, c_uint, c_uint, c_uint) libsteps.api_get_powerflow_solver_integer_parameter.restype = (c_uint) libsteps.api_get_powerflow_solver_integer_parameter.argtypes = (c_char_p, c_uint) @@ -654,6 +691,8 @@ def load_library(): libsteps.api_prepare_transformer_related_meters.argtypes = (c_uint, ) libsteps.api_prepare_hvdc_related_meters.restype = None libsteps.api_prepare_hvdc_related_meters.argtypes = (c_uint, ) + libsteps.api_prepare_vsc_hvdc_related_meters.restype = None + libsteps.api_prepare_vsc_hvdc_related_meters.argtypes = (c_uint, ) libsteps.api_prepare_equivalent_device_related_meters.restype = None libsteps.api_prepare_equivalent_device_related_meters.argtypes = (c_uint, ) @@ -676,6 +715,8 @@ def load_library(): libsteps.api_prepare_transformer_related_meter.argtypes = (c_uint, c_uint, c_uint, c_char_p, c_char_p, c_char_p, c_char_p, c_uint) libsteps.api_prepare_hvdc_related_meter.restype = None libsteps.api_prepare_hvdc_related_meter.argtypes = (c_uint, c_uint, c_char_p, c_char_p, c_char_p, c_char_p, c_uint) + libsteps.api_prepare_vsc_hvdc_related_meter.restype = None + libsteps.api_prepare_vsc_hvdc_related_meter.argtypes = (c_char_p, c_char_p, c_uint,c_char_p, c_uint) libsteps.api_prepare_equivalent_device_related_meter.restype = None libsteps.api_prepare_equivalent_device_related_meter.argtypes = (c_uint, c_char_p, c_char_p, c_char_p, c_uint) @@ -792,6 +833,15 @@ def load_library(): libsteps.api_set_hvdc_power_order_in_MW.restype = None libsteps.api_set_hvdc_power_order_in_MW.argtypes = (c_uint, c_uint, c_char_p, c_double, c_uint) + libsteps.api_set_vsc_hvdc_dc_line_fault.restype = None + libsteps.api_set_vsc_hvdc_dc_line_fault.argtypes = (c_char_p, c_uint, c_uint, c_char_p, c_double,c_double, c_uint) + libsteps.api_clear_vsc_hvdc_dc_line_fault.restype = None + libsteps.api_clear_vsc_hvdc_dc_line_fault.argtypes = (c_char_p, c_uint, c_uint, c_char_p, c_uint) + libsteps.api_trip_vsc_hvdc_dc_line.restype = None + libsteps.api_trip_vsc_hvdc_dc_line.argtypes = (c_char_p, c_uint, c_uint, c_char_p, c_uint) + libsteps.api_close_vsc_hvdc_dc_line.restype = None + libsteps.api_close_vsc_hvdc_dc_line.argtypes = (c_char_p, c_uint, c_uint, c_char_p, c_uint) + libsteps.api_search_cct.restype = (c_double) libsteps.api_search_cct.argtypes = (c_char_p, c_char_p, c_uint, c_uint, c_char_p, c_uint, c_uint, c_uint) diff --git a/python/stepspy-current/stepspy/stepspy.py b/python/stepspy-current/stepspy/stepspy.py index 79bf87a3..ecf05dc3 100644 --- a/python/stepspy-current/stepspy/stepspy.py +++ b/python/stepspy-current/stepspy/stepspy.py @@ -534,6 +534,17 @@ def get_hvdc_capacity(self): device = self.__get_c_char_p_of_string("HVDC") return int(STEPS_LIB.api_get_device_capacity(device, self.toolkit_index)) + def get_vsc_hvdc_capacity(self): + """ + Get capacity for storing VSC HVDC projects in database. + Args: N/A + Rets: + (1) Maximum number of VSC HVDC projects that can be stored in the database. + """ + global STEPS_LIB + device = self.__get_c_char_p_of_string("VSC HVDC") + return int(STEPS_LIB.api_get_device_capacity(device, self.toolkit_index)) + def get_equivalent_device_capacity(self): """ Get capacity for storing equivalent devices in database. @@ -625,6 +636,7 @@ def set_wt_generator_capacity(self, capacity): global STEPS_LIB device = self.__get_c_char_p_of_string("Wt Generator") return STEPS_LIB.api_set_device_capacity(device, capacity, self.toolkit_index) + def set_pv_unit_capacity(self, capacity): """ Set capacity for storing PV units in database. @@ -723,6 +735,19 @@ def set_hvdc_capacity(self, capacity): device = self.__get_c_char_p_of_string("HVDC") return STEPS_LIB.api_set_device_capacity(device, capacity, self.toolkit_index) + def set_vsc_hvdc_capacity(self, capacity): + """ + Set capacity for storing VSC HVDC projects in database. + Args: + (1) capacity: Maximum number of VSC HVDC projects that can be stored in the database. + Rets: N/A + Tips: + This function SHOULD be called before adding devices to the database. + """ + global STEPS_LIB + device = self.__get_c_char_p_of_string("VSC HVDC") + return STEPS_LIB.api_set_device_capacity(device, capacity, self.toolkit_index) + def set_equivalent_device_capacity(self, capacity): """ Set capacity for storing equivalent devices in database. @@ -912,6 +937,19 @@ def add_hvdc(self, hvdc): STEPS_LIB.api_add_hvdc(ibus, jbus, ickt, self.toolkit_index) return + def add_vsc_hvdc(self, vschvdc): + """ + Add new VSC HVDC project with project name. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + Rets: N/A + Example: N/A + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + STEPS_LIB.api_add_vsc_hvdc(vschvdc, self.toolkit_index) + return + def add_transformer(self, transformer): """ Add new transformer with device id. @@ -1108,6 +1146,19 @@ def remove_hvdc(self, hvdc): STEPS_LIB.api_remove_hvdc(ibus, jbus, ickt, self.toolkit_index) return + def remove_vsc_hvdc(self, vschvdc): + """ + Remove VSC HVDC project with project name. + Args: + (1) vschvdc: VSC HVDC projecct name in format of string. + Rets: N/A + Example: N/A + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + STEPS_LIB.api_remove_vsc_hvdc(vschvdc, self.toolkit_index) + return + def remove_transformer(self, transformer): """ Remove transformer with device id. @@ -1230,6 +1281,7 @@ def get_bus_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("BUS") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_generator_count(self): """ Return number of generators. @@ -1241,6 +1293,7 @@ def get_generator_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("Generator") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_wt_generator_count(self): """ Return number of wind turbine generators. @@ -1252,6 +1305,7 @@ def get_wt_generator_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("WT Generator") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_pv_unit_count(self): """ Return number of PV units. @@ -1263,6 +1317,7 @@ def get_pv_unit_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("PV Unit") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_load_count(self): """ Return number of loads. @@ -1274,6 +1329,7 @@ def get_load_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("Load") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_fixed_shunt_count(self): """ Return number of fixed shunt. @@ -1285,6 +1341,7 @@ def get_fixed_shunt_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("Fixed Shunt") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_line_count(self): """ Return number of transmission lines. @@ -1296,6 +1353,7 @@ def get_line_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("Line") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_transformer_count(self): """ Return number of transformers. @@ -1307,6 +1365,7 @@ def get_transformer_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("Transformer") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_hvdc_count(self): """ Return number of HVDC links. @@ -1318,6 +1377,18 @@ def get_hvdc_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("HVDC") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + + def get_vsc_hvdc_count(self): + """ + Return number of VSC HVDC projects. + Args: N/A + Rets: + (1) Number of VSC HVDC projects. + """ + global STEPS_LIB + device = self.__get_c_char_p_of_string("VSC HVDC") + return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_equivalent_device_count(self): """ Return number of equivalent devices. @@ -1329,6 +1400,7 @@ def get_equivalent_device_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("Equivalent Device") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_energy_storage_count(self): """ Return number of energy storages. @@ -1340,6 +1412,7 @@ def get_energy_storage_count(self): global STEPS_LIB device = self.__get_c_char_p_of_string("Energy Storage") return STEPS_LIB.api_get_device_count(device, self.toolkit_index) + def get_area_count(self): """ Return number of areas. @@ -1350,6 +1423,7 @@ def get_area_count(self): """ global STEPS_LIB return STEPS_LIB.api_get_area_count(self.toolkit_index) + def get_zone_count(self): """ Return number of zones. @@ -1360,6 +1434,7 @@ def get_zone_count(self): """ global STEPS_LIB return STEPS_LIB.api_get_zone_count(self.toolkit_index) + def get_owner_count(self): """ Return number of owners. @@ -1370,6 +1445,7 @@ def get_owner_count(self): """ global STEPS_LIB return STEPS_LIB.api_get_owner_count(self.toolkit_index) + def get_in_service_bus_count(self): """ Return number of in-service buses. @@ -1381,6 +1457,7 @@ def get_in_service_bus_count(self): global STEPS_LIB STEPS_LIB.api_get_in_service_bus_count(self.toolkit_index) return + def update_overshadowed_buses(self): """ Update overshowed buses. @@ -1390,6 +1467,7 @@ def update_overshadowed_buses(self): """ global STEPS_LIB return STEPS_LIB.api_update_overshadowed_buses(self.toolkit_index) + def set_all_buses_un_overshadowed(self): """ Set all buses as un-overshowed. @@ -1400,6 +1478,7 @@ def set_all_buses_un_overshadowed(self): global STEPS_LIB STEPS_LIB.api_set_all_buses_un_overshadowed(self.toolkit_index) return + def get_overshadowed_bus_count(self): """ Get number of overshowed buses. If there are n buses directly connected by zero impedance line or lines, n-1 buses are overshadowed by one of them. @@ -1539,6 +1618,19 @@ def is_hvdc_exist(self, hvdc): ickt = self.__get_c_char_p_of_string(ickt) return STEPS_LIB.api_is_hvdc_exist(ibus, jbus, ickt, self.toolkit_index) + def is_vsc_hvdc_exist(self, vschvdc): + """ + Check if given VSC HVDC project exists or not. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + Rets: + (1) True if the VSC HVDC project exists, False otherwise. + Example: N/A + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + return STEPS_LIB.api_is_vsc_hvdc_exist(vschvdc, self.toolkit_index) + def is_equivalent_device_exist(self, equivalent_device): """ Check if given equivalent device exists or not. @@ -2065,6 +2157,39 @@ def get_hvdcs_between_buses(self, ibus, jbus): dcs.append(dc) return tuple(dcs) + def get_all_vsc_hvdcs(self): + """ + Get all VSC HVDC projects in the database. + Args: N/A + Rets: + (1) Tuple of all VSC HVDC projects. Empty tuple if no VSC HVDC projects in the database. + """ + return self.get_vsc_hvdcs_at_bus(0) + + def get_vsc_hvdcs_at_bus(self, bus): + """ + Get all VSC HVDC projects at bus with input bus number. + Args: + (1) bus: bus number + Rets: + (1) Tuple of all VSC HVDC projects at given bus. Empty tuple if no VSC HVDC projects at given bus. + """ + global STEPS_LIB + device = "VSC HVDC" + device = self.__get_c_char_p_of_string(device) + blank = self.__get_c_char_p_of_string("") + STEPS_LIB.api_initialize_device_search(device, bus, self.toolkit_index) + vscs = [] + while True: + nbus = STEPS_LIB.api_get_current_device_bus_number(device, blank, self.toolkit_index) + if nbus==0: + break + id = STEPS_LIB.api_get_current_device_identifier(device, self.toolkit_index) + id = self.__get_string_from_c_char_p(id) + vscs.append((int(nbus), id)) + STEPS_LIB.api_goto_next_device(device, self.toolkit_index) + return tuple(vscs) + def get_generators_with_constraints(self, area=0, zone=0): """ Get all generators satisfying area and zone constraints. @@ -2591,6 +2716,40 @@ def get_hvdc_data(self, hvdc, par_type, side, par_name): return self.__get_string_from_c_char_p(STEPS_LIB.api_get_hvdc_string_data(ibus, jbus, ickt, side, par_name, self.toolkit_index)) return None + def get_vsc_hvdc_data(self, vschvdc, dev_type, par_type, par_name, index): + """ + Get VSC HVDC project data. + Args: + (1) vschvdc: VSC HVDC project name + (2) dev_type: String of device type. Choose one from("PROJECT", "CONVERTER", "DC BUS", "DC LINE") + (3) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (4) par_name: String of parameter name. + (5) index: Int of converter or dc bus or dc line index + Rets: + (1) Value of parameter. + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, 0, 0.0, "", or False will be returned. + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN', 'S', 'STRING']: + return None + dev_type = dev_type.upper() + par_name = par_name.upper() + vschvdc = self.__get_c_char_p_of_string(vschvdc) + dev_type = self.__get_c_char_p_of_string(dev_type) + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return int(STEPS_LIB.api_get_vsc_hvdc_integer_data(vschvdc, dev_type, par_name, index, self.toolkit_index)) + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_get_vsc_hvdc_float_data(vschvdc, dev_type, par_name, index, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return STEPS_LIB.api_get_vsc_hvdc_boolean_data(vschvdc, dev_type, par_name, index, self.toolkit_index) + if par_type in ['S', 'STRING']: + return self.__get_string_from_c_char_p(STEPS_LIB.api_get_vsc_hvdc_string_data(vschvdc, dev_type, par_name, index, self.toolkit_index)) + return None + def get_area_data(self, area, par_type, par_name): """ Get area data. @@ -3103,6 +3262,7 @@ def set_hvdc_data(self, hvdc, par_type, side, par_name, value): value = self.__get_c_char_p_of_string(value) return STEPS_LIB.api_set_hvdc_string_data(ibus, jbus, ickt, side, par_name, value, self.toolkit_index) return + def set_hvdc_power(self, hvdc, p): """ Set HVDC link power command. @@ -3117,6 +3277,41 @@ def set_hvdc_power(self, hvdc, p): self.set_hvdc_data(hvdc, "F", "HVDC", "PDCN_MW", p) return + def set_vsc_hvdc_data(self, vschvdc, dev_type, par_type, par_name, value, index): + """ + Set VSC HVDC project data. + Args: + (1) vschvdc: VSC HVDC project name + (2) dev_type: String of device type. Choose one from("PROJECT", "CONVERTER", "DC BUS", "DC LINE") + (3) par_type: String of parameter type. Choose one from {"I", "F", "D", "S", "B"}. + (4) par_name: String of parameter name. + (5) value: Value of parameter. + (6) index: Int of converter or dc bus or dc line index + Rets: N/A + Tips: + The par_type meaning: "I": integer number, "F" or "D": float number, "S": string, "B": boolean data. + The type of given parameter MUST be consistent with the given parameter type. Otherwise, nothing will be done. + """ + global STEPS_LIB + par_type = par_type.upper() + if par_type not in ['I', 'INT', 'INTEGER', 'F', 'D', 'FLOAT', 'DOUBLE', 'B', 'BOOL', 'BOOLEAN', 'S', 'STRING']: + return None + dev_type = dev_type.upper() + par_name = par_name.upper() + vschvdc = self.__get_c_char_p_of_string(vschvdc) + dev_type = self.__get_c_char_p_of_string(dev_type) + par_name = self.__get_c_char_p_of_string(par_name) + if par_type in ['I', 'INT', 'INTEGER']: + return int(STEPS_LIB.api_set_vsc_hvdc_integer_data(vschvdc, dev_type, par_name, value, index, self.toolkit_index)) + if par_type in ['F', 'D', 'FLOAT', 'DOUBLE']: + return STEPS_LIB.api_set_vsc_hvdc_float_data(vschvdc, dev_type, par_name, value, index, self.toolkit_index) + if par_type in ['B', 'BOOL', 'BOOLEAN']: + return STEPS_LIB.api_set_vsc_hvdc_boolean_data(vschvdc, dev_type, par_name, value, index, self.toolkit_index) + if par_type in ['S', 'STRING']: + value = self.__get_c_char_p_of_string(value) + return self.__get_string_from_c_char_p(STEPS_LIB.api_set_vsc_hvdc_string_data(vschvdc, dev_type, par_name, value, index, self.toolkit_index)) + return None + def set_area_data(self, area, par_type, par_name, value): """ Set area data. @@ -3224,6 +3419,19 @@ def load_powerflow_data(self, file, ftype): ftype = self.__get_c_char_p_of_string(ftype) STEPS_LIB.api_load_powerflow_data_from_file(file, ftype, self.toolkit_index) + def load_vsc_hvdc_powerflow_data(self, file, ftype): + """ + Load VSC HVDC powerflow data from file. + Args: + (1) file: string, source VSC HVDC powerflow file name. + (2) ftype: string, powerflow data format. + Rets: N/A + """ + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + ftype = self.__get_c_char_p_of_string(ftype) + STEPS_LIB.api_load_vsc_hvdc_powerflow_data_from_file(file, ftype, self.toolkit_index) + def check_powerflow_data(self): """ Check powerflow data. If any inappropriate data is set, report will be sent to log file. @@ -3260,6 +3468,20 @@ def save_powerflow_data(self, file, ftype, export_zero_line=True, export_out_of_ else: print("parameter export_mode is invalid in save_powerflow_data()") + def save_vsc_hvdc_powerflow_data(self, file, ftype): + """ + Save VSC HVDC powerflow data to file + Args: + (1) file: string, target powerflow file name. + (2) ftype: string, powerflow data format. + Rets: N/A + """ + + global STEPS_LIB + file = self.__get_c_char_p_of_string(file) + ftype = self.__get_c_char_p_of_string(ftype) + STEPS_LIB.api_save_vsc_hvdc_powerflow_data_to_file(file, ftype, self.toolkit_index) + def __save_powerflow_data_in_keep_mode(self, file, ftype, export_zero_line=True, export_out_of_service_bus=True, export_internal_bus_number=False): """ Save powerflow data to file in keep as original mode @@ -4357,6 +4579,89 @@ def get_hvdc_related_model_parameter_pair(self, hvdc, model_type): parameters.append((par_name, par_value)) return tuple(parameters) + def get_vsc_hvdc_related_model_name(self, vschvdc, model_type): + """ + Get VSC HVDC project related model name. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) model_type: String of model type. + Rets: + (1) String of model name. + Tips: + If model type is not supported, empty string is returned. + Example: N/A + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + model_type = self.__get_c_char_p_of_string(model_type) + model_name = self.__get_string_from_c_char_p(STEPS_LIB.api_get_vsc_hvdc_related_model_name(vschvdc, model_type, self.toolkit_index)) + if model_name=="": + model_name = None + return model_name + + def get_vsc_hvdc_related_model_data(self, vschvdc, model_type, par_name): + """ + Get VSC HVDC project related model data. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) model_type: String of model type. + (3) par_name: String of parameter name. + Rets: + (1) Value of parameter + Tips: + If model type or parameter name is not supported, 0.0 is returned. + Example: N/A + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + model_type = self.__get_c_char_p_of_string(model_type) + par_name = self.__get_c_char_p_of_string(par_name) + return STEPS_LIB.api_get_vsc_hvdc_related_model_float_parameter(vschvdc, model_type, par_name, self.toolkit_index) + + def set_vsc_hvdc_related_model_data(self, vschvdc, model_type, par_name, value): + """ + Set VSC HVDC project related model data. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) model_type: String of model type. + (3) par_name: String of parameter name. + (4) value: Value of parameter. + Rets: N/A + Tips: + If model type or parameter name is not supported, nothing will be changed. + If value is not a number, function may malfunction and package may exit with error. + Example: N/A + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + model_type = self.__get_c_char_p_of_string(model_type) + par_name = self.__get_c_char_p_of_string(par_name) + return STEPS_LIB.api_set_vsc_hvdc_related_model_float_parameter(vschvdc, model_type, par_name, value, self.toolkit_index) + + def get_vsc_hvdc_related_model_parameter_pair(self, vschvdc, model_type): + """ + Get VSC HVDC project related model parameter pair. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) model_type: String of model type. + Rets: + (1) Tuple of parameter name and value pairs. Each parameter name and value pair is in format of (string of parameter name, value of parameter). + Tips: + If model type is not supported, empty tuple is returned. + Example: N/A + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + model_type = self.__get_c_char_p_of_string(model_type) + parameters = [] + n = STEPS_LIB.api_get_vsc_hvdc_related_model_float_parameter_count(vschvdc, model_type, self.toolkit_index) + for parameter_index in range(n): + par_name = STEPS_LIB.api_get_vsc_hvdc_related_model_float_parameter_name(vschvdc, model_type, parameter_index, self.toolkit_index) + par_value = STEPS_LIB.api_get_vsc_hvdc_related_model_float_parameter(vschvdc, model_type, par_name, self.toolkit_index); + par_name = self.__get_string_from_c_char_p(par_name) + parameters.append((par_name, par_value)) + return tuple(parameters) + def get_generator_governor_pmax(self, gen): """ Get generator pmax in MW from turbine governor model. @@ -4644,13 +4949,12 @@ def prepare_meters(self, device_type): DYNAMIC_SIMULATOR::prepare_line_related_meters() DYNAMIC_SIMULATOR::prepare_transformer_related_meters() DYNAMIC_SIMULATOR::prepare_hvdc_related_meters() + DYNAMIC_SIMULATOR::prepare_vsc_hvdc_related_meters() DYNAMIC_SIMULATOR::prepare_equivalent_device_related_meters() Example: N/A """ global STEPS_LIB device_type = device_type.upper() - if device_type not in ['ALL', 'BUS', 'GENERATOR', 'WT GENERATOR', 'PV UNIT', 'ENERGY STORAGE', 'LOAD', 'LINE', 'TRANSFORMER', 'HVDC', 'EQUIVALENT DEVICE']: - return if device_type in ['ALL']: STEPS_LIB.api_prepare_meters(self.toolkit_index) return @@ -4681,6 +4985,9 @@ def prepare_meters(self, device_type): if device_type in ['HVDC']: STEPS_LIB.api_prepare_hvdc_related_meters(self.toolkit_index) return + if device_type in ['VSC HVDC']: + STEPS_LIB.api_prepare_vsc_hvdc_related_meters(self.toolkit_index) + return if device_type in ['EQUIVALENT DEVICE']: STEPS_LIB.api_prepare_equivalent_device_related_meters(self.toolkit_index) return @@ -4878,6 +5185,27 @@ def prepare_hvdc_meter(self, hvdc, meter_type, side, var_name=""): STEPS_LIB.api_prepare_hvdc_related_meter(ibus, jbus, ickt, meter_type, side, var_name, self.toolkit_index) return + def prepare_vsc_hvdc_meter(self, vschvdc, meter_type, side, var_name=""): + """ + Prepare specific VSC HVDC project meter. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) meter_type: String of meter type. + (3) side: index of Converter or DC line. + (4) var_name: String of internal variable name. Only valid when meter type is internal variable of dynamic models. + Rets: N/A + Tips: + For the supported meter types, see implementation of the following function of STEPS: + DYNAMIC_SIMULATOR::prepare_vsc_hvdc_related_meter() + Example: N/A + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + meter_type = self.__get_c_char_p_of_string(meter_type) + var_name = self.__get_c_char_p_of_string(var_name) + STEPS_LIB.api_prepare_vsc_hvdc_related_meter(vschvdc, meter_type, side, var_name, self.toolkit_index) + return + def prepare_equivalent_device_meter(self, edevice, meter_type, var_name=""): """ Prepare specific equivalent device meter. @@ -5791,4 +6119,91 @@ def set_hvdc_power_order_in_MW(self, hvdc, value): ibus, jbus, ickt = self.__extract_double_bus_device_id(hvdc) ickt = self.__get_c_char_p_of_string(ickt) return STEPS_LIB.api_set_hvdc_power_order_in_MW(ibus, jbus, ickt, value, self.toolkit_index) - \ No newline at end of file + + def set_vsc_hvdc_dc_line_fault(self, vschvdc, line, fault_location, fault_r): + """ + Set VSC HVDC DC line fault. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) line: DC line device id in format of (ibus, jbus, ickt). + (3) fault_location: Relative fault location to ibus. + (4) fault_r: Fault resistance in Ohm. + Rets: N/A + Tips: + The fault location should be in the range of [0, 1.0], including 0 and 1.0. It represent the relative location of the fault on the line to the ibus. + For example, 0.5 means the fault is set at the middle of the line. 0 means the fault is set at exactly ibus. 1.0 means the fault is set at exactly jbus. + The absolute value of the fault shunt should not be too great. Otherwise, network solution may fail to converge. Typically, |b|<1e6. + Example: + vschvdc = "VSC ProjectA" + line = (1, 2, "1#") + location = 0.2 + fault_r = 10 + simulator.set_vsc_hvdc_dc_line_fault(vschvdc, line, location, shunt) + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + ibus, jbus, ickt = self.__extract_double_bus_device_id(line) + ickt = self.__get_c_char_p_of_string(ickt) + STEPS_LIB.api_set_vsc_hvdc_dc_line_fault(vschvdc, ibus, jbus, ickt, fault_location, fault_r, self.toolkit_index) + return + + def clear_vsc_hvdc_dc_line_fault(self, vschvdc, line): + """ + Clear VSC HVDC DC line fault without tripping the line. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) line: DC line device id in format of (ibus, jbus, ickt). + Rets: N/A + Tips: N/A + Example: + vschvdc = "VSC ProjectA" + line = (1, 2, "1#") + location = 0.2 + fault_r = 10 + simulator.set_vsc_hvdc_dc_line_fault(vschvdc, line, location, shunt) + simulator.clear_vsc_hvdc_dc_line_fault(vschvdc, line) + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + ibus, jbus, ickt = self.__extract_double_bus_device_id(line) + ickt = self.__get_c_char_p_of_string(ickt) + STEPS_LIB.api_clear_vsc_hvdc_dc_line_fault(vschvdc, ibus, jbus, ickt, self.toolkit_index) + return + + def trip_vsc_hvdc_dc_line(self, vschvdc, line): + """ + Trip VSC HVDC DC line. Breakers at the two sides of the line are both tripped. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) line: DC line device id in format of (ibus, jbus, ickt). + Rets: N/A + Example: + vschvdc = "VSC ProjectA" + line = (1, 2, "1#") + simulator.trip_vsc_hvdc_dc_line(vschvdc, line) + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + ibus, jbus, ickt = self.__extract_double_bus_device_id(line) + ickt = self.__get_c_char_p_of_string(ickt) + STEPS_LIB.api_trip_vsc_hvdc_dc_line(vschvdc, ibus, jbus, ickt, self.toolkit_index) + return + + def close_vsc_hvdc_dc_line(self, vschvdc, line): + """ + Close VSC HVDC DC line. Breakers at the two sides of the line are both closed. + Args: + (1) vschvdc: VSC HVDC project name in format of string. + (2) line: DC line device id in format of (ibus, jbus, ickt). + Rets: N/A + Example: + vschvdc = "VSC ProjectA" + line = (1, 2, "1#") + simulator.close_vsc_hvdc_dc_line(vschvdc, line) + """ + global STEPS_LIB + vschvdc = self.__get_c_char_p_of_string(vschvdc) + ibus, jbus, ickt = self.__extract_double_bus_device_id(line) + ickt = self.__get_c_char_p_of_string(ickt) + STEPS_LIB.api_close_vsc_hvdc_dc_line(vschvdc, ibus, jbus, ickt, self.toolkit_index) + return \ No newline at end of file