def parse_loads(self, cim: CIMCircuit, circuit: MultiCircuit, busbar_dict): """ :param cim: :param circuit: :param busbar_dict: :return: """ cim_loads = ['ConformLoad', 'EnergyConsumer', 'NonConformLoad'] if any_in_dict(cim.elements_by_type, cim_loads): for elm in get_elements(cim.elements_by_type, cim_loads): b1 = elm.get_bus() B1 = try_bus(b1, busbar_dict) if B1 is not None: p, q = elm.get_pq() load = gcdev.Load(idtag=elm.uuid, name=str(elm.name), G=0, B=0, Ir=0, Ii=0, P=p if p is not None else 0, Q=q if q is not None else 0) circuit.add_load(B1, load) else: self.logger.add_error('Bus not found', elm.rfid)
def parse_switches(self, cim: CIMCircuit, circuit: MultiCircuit, busbar_dict): """ :param cim: :param circuit: :param busbar_dict: :return: """ EPS = 1e-20 cim_switches = ['Switch', 'Disconnector', 'Breaker', 'LoadBreakSwitch'] if any_in_dict(cim.elements_by_type, cim_switches): for elm in get_elements(cim.elements_by_type, cim_switches): b1, b2 = elm.get_buses() B1, B2 = try_buses(b1, b2, busbar_dict) if B1 is not None and B2 is not None: state = True line = gcdev.Switch(idtag=elm.uuid, bus_from=B1, bus_to=B2, name=str(elm.name), r=EPS, x=EPS, rate=EPS, active=state) circuit.add_switch(line) else: self.logger.add_error('Bus not found', elm.rfid)
def parse_power_transformer(self, cim: CIMCircuit, circuit: MultiCircuit, busbar_dict): """ :param cim: :param circuit: :param busbar_dict: :return: """ if 'PowerTransformer' in cim.elements_by_type.keys(): for elm in cim.elements_by_type['PowerTransformer']: b1, b2 = elm.get_buses() B1, B2 = try_buses(b1, b2, busbar_dict) if B1 is not None and B2 is not None: R, X, G, B = elm.get_pu_values() rate = elm.get_rate() voltages = elm.get_voltages() voltages.sort() if len(voltages) == 2: lv, hv = voltages else: lv = 1 hv = 1 self.logger.add_error( 'Could not parse transformer nominal voltages', self.name) line = gcdev.Transformer2W(idtag=cimdev.rfid2uuid( elm.rfid), bus_from=B1, bus_to=B2, name=str(elm.name), r=R, x=X, g=G, b=B, rate=rate, tap=1.0, shift_angle=0, active=True, HV=hv, LV=lv) circuit.add_branch(line) else: self.logger.add_error('Bus not found', elm.rfid)
def parse_bus_bars(self, cim: CIMCircuit, circuit: MultiCircuit): """ :param cim: :param circuit: :return: """ busbar_dict = dict() if 'BusbarSection' in cim.elements_by_type.keys(): for elm in cim.elements_by_type['BusbarSection']: obj = gcdev.Bus(name=str(elm.name), idtag=elm.uuid) circuit.add_bus(obj) busbar_dict[elm] = obj else: self.logger.add_error( "No BusbarSections: There is no chance to reduce the grid") return busbar_dict
def parse_ac_line_segment(self, cim: CIMCircuit, circuit: MultiCircuit, busbar_dict): """ :param cim: :param circuit: :param busbar_dict: :return: """ if 'ACLineSegment' in cim.elements_by_type.keys(): for elm in cim.elements_by_type['ACLineSegment']: b1, b2 = elm.get_buses() B1, B2 = try_buses(b1, b2, busbar_dict) if B1 is not None and B2 is not None: R, X, G, B = elm.get_pu_values() rate = elm.get_rate() # create AcLineSegment (Line) line = gcdev.Line(idtag=elm.uuid, bus_from=B1, bus_to=B2, name=str(elm.name), r=R, x=X, b=B, rate=rate, active=True, mttf=0, mttr=0) circuit.add_line(line) else: self.logger.add_error('Bus not found', elm.rfid)
def parse_generators(self, cim: CIMCircuit, circuit: MultiCircuit, busbar_dict): """ :param cim: :param circuit: :param busbar_dict: :return: """ if 'SynchronousMachine' in cim.elements_by_type.keys(): for elm in cim.elements_by_type['SynchronousMachine']: b1 = elm.get_bus() B1 = try_bus(b1, busbar_dict) if B1 is not None: gen = gcdev.Generator(idtag=elm.uuid, name=str(elm.name), active_power=elm.p, voltage_module=1.0) circuit.add_generator(B1, gen) else: self.logger.add_error('Bus not found', elm.rfid)
def parse_shunts(self, cim: CIMCircuit, circuit: MultiCircuit, busbar_dict): """ :param cim: :param circuit: :param busbar_dict: :return: """ if 'ShuntCompensator' in cim.elements_by_type.keys(): for elm in cim.elements_by_type['ShuntCompensator']: b1 = elm.get_bus() B1 = try_bus(b1, busbar_dict) if B1 is not None: g = 0 b = 0 sh = gcdev.Shunt(idtag=elm.uuid, name=str(elm.name), G=g, B=b) circuit.add_shunt(B1, sh) else: self.logger.add_error('Bus not found', elm.rfid)
def get_objects_dictionary(): """ creates a dictionary with the types and the circuit objects :return: Dictionary instance """ object_types = {'area': dev.Area(), 'zone': dev.Zone(), 'substation': dev.Substation(), 'country': dev.Country(), 'bus': dev.Bus(), 'load': dev.Load(), 'static_generator': dev.StaticGenerator(), 'battery': dev.Battery(), 'generator': dev.Generator(), 'shunt': dev.Shunt(), 'wires': dev.Wire(), 'overhead_line_types': dev.Tower(), 'underground_cable_types': dev.UndergroundLineType(), 'sequence_line_types': dev.SequenceLineType(), 'transformer_types': dev.TransformerType(), 'branch': dev.Branch(), 'transformer2w': dev.Transformer2W(), 'line': dev.Line(), 'dc_line': dev.DcLine(None, None), 'hvdc': dev.HvdcLine(), 'vsc': dev.VSC(None, None), 'upfc': dev.UPFC(None, None), } return object_types
def data_frames_to_circuit(data: Dict): """ Interpret data dictionary :param data: dictionary of data frames :return: MultiCircuit instance """ # create circuit circuit = MultiCircuit() if 'name' in data.keys(): circuit.name = str(data['name']) if circuit.name == 'nan': circuit.name = '' # set the base magnitudes if 'baseMVA' in data.keys(): circuit.Sbase = data['baseMVA'] # Set comments if 'Comments' in data.keys(): circuit.comments = str(data['Comments']) if circuit.comments == 'nan': circuit.comments = '' if 'ModelVersion' in data.keys(): circuit.model_version = int(data['ModelVersion']) if 'UserName' in data.keys(): circuit.user_name = data['UserName'] # dictionary of objects to iterate object_types = get_objects_dictionary() circuit.logger = Logger() # time profile ----------------------------------------------------------------------------------------------------- if 'time' in data.keys(): time_df = data['time'] circuit.time_profile = pd.to_datetime(time_df.values[:, 0], dayfirst=True) else: circuit.time_profile = None # dictionary of dictionaries by element type # elements_dict[DataType][element_name] = actual object elements_dict = dict() elements_dict_by_name = dict() # ------------------------------------------------------------------------------------------------------------------ # for each element type... for key, template_elm in object_types.items(): if key in data.keys(): # get the DataFrame df = data[key] # create the objects ... devices = list() devices_dict = dict() if 'idtag' in df.columns.values: for i in range(df.shape[0]): elm = type(template_elm)() idtag = df['idtag'].values[i] # create the buses dictionary, this works because the bus is the first key in "object_types" devices_dict[idtag] = elm # add the device to the elements devices.append(elm) else: for i in range(df.shape[0]): elm = type(template_elm)() idtag = df['name'].values[i] # create the buses dictionary, this works because the bus is the first key in "object_types" devices_dict[idtag] = elm # add the device to the elements devices.append(elm) elements_dict[template_elm.device_type] = devices_dict # fill in the objects if df.shape[0] > 0: # for each property ... for object_property_name, gc_prop in template_elm.editable_headers.items(): # if the object property exists in the data file, set all the object's property if object_property_name in df.columns.values: # get the type converter dtype = gc_prop.tpe # for each object, set the property for i in range(df.shape[0]): # convert and assign the data if dtype is None: val = df[object_property_name].values[i] setattr(devices[i], object_property_name, val) elif dtype in [DeviceType.SubstationDevice, DeviceType.AreaDevice, DeviceType.ZoneDevice, DeviceType.CountryDevice]: """ This piece is to assign the objects matching the Area, Substation, Zone and Country The cases may be: a) there is a matching id tag -> ok, assign it b) the value is a string -> create the relevant object, make sure it is not repeated by name inset the object in its matching object dictionary """ # search for the Substation, Area, Zone or Country matching object and assign the object # this is the stored string (either idtag or name...) val = str(df[object_property_name].values[i]) if dtype not in elements_dict.keys(): elements_dict[dtype] = dict() if dtype not in elements_dict_by_name.keys(): elements_dict_by_name[dtype] = dict() if val in elements_dict[dtype].keys(): # the grouping exists as object, use it grouping = elements_dict[dtype][val] else: # create the grouping if val in elements_dict_by_name[dtype].keys(): grouping = elements_dict_by_name[dtype][val] else: grouping = type(object_types[dtype.value.lower()])(name=val) elements_dict[dtype][grouping.idtag] = grouping # store also by name elements_dict_by_name[dtype][grouping.name] = grouping # set the object setattr(devices[i], object_property_name, grouping) elif dtype == DeviceType.BusDevice: # check if the bus is in the dictionary... if df[object_property_name].values[i] in elements_dict[DeviceType.BusDevice].keys(): parent_bus: dev.Bus = elements_dict[DeviceType.BusDevice][df[object_property_name].values[i]] setattr(devices[i], object_property_name, parent_bus) # add the device to the bus if template_elm.device_type in [DeviceType.LoadDevice, DeviceType.GeneratorDevice, DeviceType.BatteryDevice, DeviceType.StaticGeneratorDevice, DeviceType.ShuntDevice, DeviceType.ExternalGridDevice]: parent_bus.add_device(devices[i]) else: circuit.logger.add_error('Bus not found', str(df[object_property_name].values[i])) elif dtype in [DeviceType.TransformerTypeDevice, # template types mostly DeviceType.SequenceLineDevice, DeviceType.TowerDevice]: if df[object_property_name].values[i] in elements_dict[dtype].keys(): # get the actual template and set it val = elements_dict[dtype][df[object_property_name].values[i]] setattr(devices[i], object_property_name, val) else: circuit.logger.add_error(dtype.value + ' type not found', str(df[object_property_name].values[i])) elif dtype == bool: # regular types (int, str, float, etc...) val = df[object_property_name].values[i] if val == 'False': setattr(devices[i], object_property_name, False) elif val == 'True': setattr(devices[i], object_property_name, True) else: setattr(devices[i], object_property_name, bool(val)) else: # regular types (int, str, float, etc...) val = dtype(df[object_property_name].values[i]) setattr(devices[i], object_property_name, val) # search the profiles in the data and assign them if object_property_name in template_elm.properties_with_profile.keys(): # get the profile property prop_prof = template_elm.properties_with_profile[object_property_name] # build the profile property file-name to get it from the data profile_name = key + '_' + prop_prof if profile_name in data.keys(): # get the profile DataFrame dfp = data[profile_name] # for each object, set the profile for i in range(dfp.shape[1]): profile = dfp.values[:, i] setattr(devices[i], prop_prof, profile.astype(dtype)) else: circuit.logger.add_error('Profile was not found in the data', object_property_name) else: circuit.logger.add_error(object_property_name + ' of object type ' + str(template_elm.device_type) + ' not found in the input data') else: # no objects of this type pass # ensure profiles existence if circuit.time_profile is not None: for i in range(df.shape[0]): devices[i].ensure_profiles_exist(circuit.time_profile) # add the objects to the circuit (buses, branches ot template types) if template_elm.device_type == DeviceType.BusDevice: circuit.buses = devices # elif template_elm.device_type == DeviceType.SubstationDevice: # circuit.substations = devices # # elif template_elm.device_type == DeviceType.AreaDevice: # circuit.areas = devices # # elif template_elm.device_type == DeviceType.ZoneDevice: # circuit.zones = devices # # elif template_elm.device_type == DeviceType.CountryDevice: # circuit.countries = devices elif template_elm.device_type == DeviceType.BranchDevice: for d in devices: circuit.add_branch(d) # each branch needs to be converted accordingly elif template_elm.device_type == DeviceType.LineDevice: circuit.lines = devices elif template_elm.device_type == DeviceType.DCLineDevice: circuit.dc_lines = devices elif template_elm.device_type == DeviceType.Transformer2WDevice: circuit.transformers2w = devices elif template_elm.device_type == DeviceType.HVDCLineDevice: circuit.hvdc_lines = devices elif template_elm.device_type == DeviceType.UpfcDevice: circuit.upfc_devices = devices elif template_elm.device_type == DeviceType.VscDevice: for dev in devices: dev.correct_buses_connection() circuit.vsc_devices = devices elif template_elm.device_type == DeviceType.TowerDevice: circuit.overhead_line_types = devices elif template_elm.device_type == DeviceType.TransformerTypeDevice: circuit.transformer_types = devices elif template_elm.device_type == DeviceType.UnderGroundLineDevice: circuit.underground_cable_types = devices elif template_elm.device_type == DeviceType.SequenceLineDevice: circuit.sequence_line_types = devices elif template_elm.device_type == DeviceType.WireDevice: circuit.wire_types = devices else: circuit.logger.add_error('The data does not contain information about the type', str(key)) # fill in wires into towers ---------------------------------------------------------------------------------------- if 'tower_wires' in data.keys(): df = data['tower_wires'] for i in range(df.shape[0]): tower_name = df['tower_name'].values[i] wire_name = df['wire_name'].values[i] if (tower_name in elements_dict[DeviceType.TowerDevice].keys()) and \ (wire_name in elements_dict[DeviceType.WireDevice].keys()): tower = elements_dict[DeviceType.TowerDevice][tower_name] wire = elements_dict[DeviceType.WireDevice][wire_name] xpos = df['xpos'].values[i] ypos = df['ypos'].values[i] phase = df['phase'].values[i] w = dev.WireInTower(wire=wire, xpos=xpos, ypos=ypos, phase=phase) tower.wires_in_tower.append(w) # Other actions ---------------------------------------------------------------------------------------------------- circuit.logger += circuit.apply_all_branch_types() # Add the groups --------------------------------------------------------------------------------------------------- if DeviceType.SubstationDevice in elements_dict.keys(): circuit.substations = list(elements_dict[DeviceType.SubstationDevice].values()) if DeviceType.AreaDevice in elements_dict.keys(): circuit.areas = list(elements_dict[DeviceType.AreaDevice].values()) if DeviceType.ZoneDevice in elements_dict.keys(): circuit.zones = list(elements_dict[DeviceType.ZoneDevice].values()) if DeviceType.CountryDevice in elements_dict.keys(): circuit.countries = list(elements_dict[DeviceType.CountryDevice].values()) return circuit