Example #1
0
    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)
Example #2
0
    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)
Example #3
0
    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)
Example #4
0
    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
Example #5
0
    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)
Example #6
0
    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)
Example #7
0
    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)
Example #8
0
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
Example #9
0
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