Exemplo n.º 1
0
    def update_pandapower(
        self,
        net: pandapowerNet,
        source: str,
        target: str,
    ):
        """Update a pandapower model by adding the cable itself.

        Args:
            net: a pandapower network model.
            source: a bus of the cable, corresponding to ``source`` in
                ``networkx`` edge.
            target: another bus of the cable, corresponding to ``source`` in
                ``networkx`` edge.
        """
        from_bus = pp.get_element_index(net, "bus", source)
        to_bus = pp.get_element_index(net, "bus", target)
        pp.create_line_from_parameters(
            net,
            name=self.name,
            from_bus=from_bus,
            to_bus=to_bus,
            length_km=self.length_km,
            r_ohm_per_km=self.r_ohm,
            x_ohm_per_km=self.x_ohm,
            c_nf_per_km=self.c_nf,
            max_i_ka=self.max_i_ka,
            parallel=self.parallel,
        )
Exemplo n.º 2
0
    def update_pandapower(
        self,
        net: pandapowerNet,
        source: str,
        target: str,
    ):
        """Update a pandapower model by adding the transformer itself.

        Args:
            net: a pandapower network model.
            source: a bus of the transformer, corresponding to ``source`` in
                ``networkx`` edge.
            target: another bus of the transformer, corresponding to
                ``source`` in ``networkx`` edge.
        """
        hv_bus = pp.get_element_index(net, "bus", source)
        lv_bus = pp.get_element_index(net, "bus", target)
        pp.create_transformer(
            net,
            name=self.name,
            hv_bus=hv_bus,
            lv_bus=lv_bus,
            std_type=self.std_type,
            parallel=self.parallel,
        )
Exemplo n.º 3
0
def create_controllers(net, ds):
    load1= pp.get_element_index(net, "load", 'load1')
    sgen1 = pp.get_element_index(net, "sgen", 'sgen1')
    ConstControl(net, element='load', variable='p_mw', element_index=[load1],
                 data_source=ds, profile_name=["load1_p"])
    ConstControl(net, element='sgen', variable='p_mw', element_index=[sgen1],
                 data_source=ds, profile_name=["sgen1_p"])
    return net
Exemplo n.º 4
0
 def create_pp_transfomer(self, trafo):
     hv_bus = pp.get_element_index(
         self.net, "bus", trafo["connections"][0]['connectivityNodeId'])
     lv_bus = pp.get_element_index(
         self.net, "bus", trafo["connections"][1]['connectivityNodeId'])
     pp.create_transformer(self.net,
                           hv_bus=hv_bus,
                           lv_bus=lv_bus,
                           std_type="0.4 MVA 20/0.4 kV")
Exemplo n.º 5
0
 def create_pp_lines(self):
     conductors = self.assets_df[self.assets_df['type'] == "Conductor"]
     for _, conductor in conductors.iterrows():
         from_cn_id = conductor["connections"][0]['connectivityNodeId']
         to_cn_id = conductor["connections"][1]['connectivityNodeId']
         from_bus = pp.get_element_index(self.net, "bus", from_cn_id)
         to_bus = pp.get_element_index(self.net, "bus", to_cn_id)
         length = conductor["length"]
         if length == 0:
             length = self.min_line_length_km
         line_name = from_cn_id + "-" + to_cn_id
         pp.create_line(net=self.net,
                        name=line_name,
                        from_bus=from_bus,
                        to_bus=to_bus,
                        length_km=length,
                        std_type="NAYY 4x50 SE")
     return self.net.line
Exemplo n.º 6
0
    def add_transformer(
            self, net, name, hv_bus_id, lv_bus_id, type
            ):

        lv_bus = pp.get_element_index(
            net, 'bus', self.bus_ids_and_names[lv_bus_id]
            )

        hv_bus = pp.get_element_index(
            net, 'bus', self.bus_ids_and_names[hv_bus_id]
            )

        pp.create_transformer(
            net = net,
            hv_bus = hv_bus,
            lv_bus = lv_bus,
            std_type = type,
            name = name
            )
Exemplo n.º 7
0
    def add_switch(
            self, net, name, from_bus_id, to_bus_id, type
            ):

        from_bus = pp.get_element_index(
            net, 'bus', self.bus_ids_and_names[from_bus_id]
            )

        to_bus = pp.get_element_index(
            net, 'bus', self.bus_ids_and_names[to_bus_id]
            )

        pp.create_switch(
            net = net,
            bus = from_bus,
            element = to_bus,
            et = 'b',
            closed = True,
            type = type,
            name = name
            )
Exemplo n.º 8
0
def line_discon_low(net, n_time_steps, output_dir):
    _net = net
    index_line_5_6 = pp.get_element_index(_net, 'line', 'Line 5 to 6')
    _net.line.in_service[index_line_5_6] = False
    profiles, ds = create_data_source(_net,
                                      mode='Low Load',
                                      n_timesteps=n_time_steps)
    _net = create_controllers(_net, ds)
    time_steps = range(0, n_time_steps)
    ow = create_output_writer(_net, time_steps, output_dir)
    run_timeseries(_net, time_steps, calculate_voltage_angles=True)
    _net.line.in_service[index_line_5_6] = True
Exemplo n.º 9
0
    def add_ext_grid(
            self, net, name, bus_id
            ):

        bus = pp.get_element_index(
            net, 'bus', self.bus_ids_and_names[bus_id]
            )

        pp.create_ext_grid(
            net = net,
            bus = bus,
            name = name
            )
Exemplo n.º 10
0
    def add_line(
            self, net, name, from_bus_id, to_bus_id, type,
            c_nf_per_km, r_ohm_per_km, x_ohm_per_km, max_i_ka,
            length_km, geodata
            ):

        from_bus = pp.get_element_index(
            net, 'bus', self.bus_ids_and_names[from_bus_id]
            )

        to_bus = pp.get_element_index(
            net, 'bus', self.bus_ids_and_names[to_bus_id]
            )

        line_geodata = [ [ c.x, c.y ] for c in geodata ]

        line_type = None
        if type == 'cable':
            line_type = 'cs'
        elif type == 'line':
            line_type = 'ol'
        else:
            warnings.warn( 'unknown line type: {}'.format( type ), RuntimeWarning )
        
        pp.create_line_from_parameters(
                net = net,
                from_bus = from_bus,
                to_bus = to_bus,
                length_km = length_km,
                type = line_type,
                c_nf_per_km = c_nf_per_km,
                r_ohm_per_km = r_ohm_per_km,
                x_ohm_per_km = x_ohm_per_km,
                max_i_ka = max_i_ka,
                name = name,
                geodata = line_geodata
                )
Exemplo n.º 11
0
    def add_load(
            self, net, name, bus_id, p_kw, q_kvar
            ):

        bus = pp.get_element_index(
            net, 'bus', self.bus_ids_and_names[bus_id]
            )

        pp.create_load(
            net = net,
            bus = bus,
            p_kw = p_kw,
            q_kvar = q_kvar,
            name = name
            )
Exemplo n.º 12
0
    def update_pandapower(
        self,
        net: pandapowerNet,
        name: str,
        bus: str,
    ):
        """Update a pandapower model by adding the transformer itself.

        Args:
            net: a pandapower network model.
            name: name of the external grid.
            bus: the bus to which the external grid is attached.
        """
        bus_idx = pp.get_element_index(net, "bus", bus)
        pp.create_ext_grid(net, name=name, bus=bus_idx)
Exemplo n.º 13
0
    def update_pandapower(
        self,
        net: pandapowerNet,
        name: str,
        bus: str,
    ):
        """Update a pandapower model by adding the capacitor itself.

        Args:
            net: a pandapower network model.
            name: name of the external grid.
            bus: the bus to which the external grid is attached.
        """
        bus_idx = pp.get_element_index(net, "bus", bus)
        pp.create_shunt_as_capacitor(
            net,
            name=name,
            bus=bus_idx,
            q_mvar=self.q_mvar,
            loss_factor=self.loss_factor,
        )
Exemplo n.º 14
0
    def update_pandapower(
        self,
        net: pandapowerNet,
        name: str,
        bus: str,
    ):
        """Update a pandapower model by adding the ejection itself.

        Note:
            When the value of ``p_mw`` is negative, a generator without
            voltage control ability is added.

        Args:
            net: a pandapower network model.
            name: name of the external grid.
            bus: the bus to which the external grid is attached.
        """
        bus_idx = pp.get_element_index(net, "bus", bus)
        if self.p_mw > 0:
            pp.create_load(
                net,
                name=name,
                bus=bus_idx,
                p_mw=self.p_mw,
                q_mvar=self.q_mvar,
                const_i_percent=0,
                const_z_percent=0,
                in_service=True,
            )
        elif self.p_mw < 0:
            pp.create_sgen(
                net,
                name=name,
                bus=bus_idx,
                p_mw=self.p_mw,
                q_mvar=self.q_mvar,
            )
Exemplo n.º 15
0
    def build_pandapower(self, ac_line_segment_list_topology,
                         busbar_section_list_topology,
                         power_transformer_list_topology,
                         synchronous_machine_list_topology,
                         shunt_compensator_list_topology,
                         energy_consumer_list_topology, breaker_list_topology):

        # Create buses in pandapower network from the internal data structure
        for bb_top in busbar_section_list_topology:
            pp.create_bus(self.net, bb_top.u_nom_kv, name=bb_top.name)

        # Create lines in pandapower network from the internal data structure
        for al_top in ac_line_segment_list_topology:
            for bb_top in busbar_section_list_topology:
                if bb_top.id_ == al_top.bus_1_id:
                    from_bus = pp.get_element_index(self.net, 'bus',
                                                    bb_top.name)
                if bb_top.id_ == al_top.bus_2_id:
                    to_bus = pp.get_element_index(self.net, 'bus', bb_top.name)
            pp.create_line_from_parameters(self.net,
                                           from_bus,
                                           to_bus,
                                           al_top.length_km,
                                           al_top.r_ohm,
                                           al_top.x_ohm,
                                           0.0,
                                           al_top.i_max_ka,
                                           name=al_top.name)

        # Create transformers in pandapower network from the internal data structure
        for tr_top in power_transformer_list_topology:
            for bb_top in busbar_section_list_topology:
                if bb_top.id_ == tr_top.bus_hv_id:
                    hv_bus = pp.get_element_index(self.net, 'bus', bb_top.name)
            for bb_top in busbar_section_list_topology:
                if bb_top.id_ == tr_top.bus_lv_id:
                    lv_bus = pp.get_element_index(self.net, 'bus', bb_top.name)
            # From the transformer documentation
            power_transformer_z = (tr_top.r**2 + tr_top.x**2)**0.5
            power_transformer_vsc = 100 * power_transformer_z * tr_top.s_nom_mva
            power_transformer_vscr = 100 * tr_top.r * tr_top.s_nom_mva
            # Neglect the iron losses
            if ('hv_bus' or 'lv_bus') in locals():
                pp.create_transformer_from_parameters(self.net,
                                                      hv_bus,
                                                      lv_bus,
                                                      tr_top.s_nom_mva,
                                                      tr_top.hv_nom_kv,
                                                      tr_top.lv_nom_kv,
                                                      power_transformer_vscr,
                                                      power_transformer_vsc,
                                                      0,
                                                      0,
                                                      name=tr_top.name)
                del hv_bus
                del lv_bus

        # Create generators in pandapower network from the internal data structure
        for sm_top in synchronous_machine_list_topology:
            for bb_top in busbar_section_list_topology:
                if bb_top.id_ == sm_top.bus_id:
                    sm_bus = pp.get_element_index(self.net, 'bus', bb_top.name)
            pp.create_gen(self.net, sm_bus, sm_top.p_rated, name=sm_top.name)

        # Create shunt in pandapower network from the internal data structure
        for sh_top in shunt_compensator_list_topology:
            for bb_top in busbar_section_list_topology:
                if bb_top.id_ == sh_top.bus_id:
                    sh_bus = pp.get_element_index(self.net, 'bus', bb_top.name)
            pp.create_shunt(self.net,
                            sh_bus,
                            sh_top.q_rated_mvar,
                            vn_kv=sh_top.u_nom_kv,
                            name=sh_top.name)

        # Create loads in pandapower network from the internal data structure
        for ec_top in energy_consumer_list_topology:
            for bb_top in busbar_section_list_topology:
                if bb_top.id_ == ec_top.bus_id:
                    ec_bus = pp.get_element_index(self.net, 'bus', bb_top.name)
            pp.create_load(self.net,
                           ec_bus,
                           ec_top.p,
                           ec_top.q,
                           name=ec_top.name)

        # Comment this part if the extended XML files are used
        # Create switches
        for br_top in breaker_list_topology:
            for bb_top in busbar_section_list_topology:
                if bb_top.id_ == br_top.bus_id:
                    br_bb = pp.get_element_index(self.net, 'bus', bb_top.name)
                    for al_top in ac_line_segment_list_topology:
                        if al_top.id_ == br_top.element_id:
                            br_el = pp.get_element_index(
                                self.net, 'line', al_top.name)
                            pp.create_switch(self.net,
                                             br_bb,
                                             br_el,
                                             et='l',
                                             name=br_top.name)
                    for tr_top in power_transformer_list_topology:
                        if tr_top.id_ == br_top.element_id:
                            br_el = pp.get_element_index(
                                self.net, 'trafo', tr_top.name)
                            pp.create_switch(self.net,
                                             br_bb,
                                             br_el,
                                             et='t',
                                             name=br_top.name)
        print('Pandapower network has been created')
Exemplo n.º 16
0
 def toogle_capacitor_status(self, capSwitchName):
     switchIndex = pp.get_element_index(self.power_grid, "switch", capSwitchName)
     currentState = self.power_grid.switch.closed.loc[switchIndex]
     self.power_grid.switch.closed.loc[switchIndex] = not currentState
Exemplo n.º 17
0
 def change_capacitor_status(self, capSwitchName, closed):
     switchIndex = pp.get_element_index(self.power_grid, "switch", capSwitchName)
     self.power_grid.switch.closed.loc[switchIndex] = closed
Exemplo n.º 18
0
def from_ppc(ppc, f_hz=50, validate_conversion=False, **kwargs):
    """
    This function converts pypower case files to pandapower net structure.

    INPUT:

        **ppc** : The pypower case file.

    OPTIONAL:

        **f_hz** (float, 50) - The frequency of the network.

        **validate_conversion** (bool, False) - If True, validate_from_ppc is run after conversion.
            For running the validation, the ppc must already contain the pypower
            powerflow results or pypower must be importable.

        ****kwargs** keyword arguments for validate_from_ppc if validate_conversion is True

    OUTPUT:

        **net** : pandapower net.

    EXAMPLE:

        import pandapower.converter as pc

        from pypower import case4gs

        ppc_net = case4gs.case4gs()

        net = pc.from_ppc(ppc_net, f_hz=60)

    """
    # --- catch common failures
    if Series(ppc['bus'][:, BASE_KV] <= 0).any():
        logger.info('There are false baseKV given in the pypower case file.')

    # --- general_parameters
    baseMVA = ppc['baseMVA']  # MVA
    omega = pi * f_hz  # 1/s
    MAX_VAL = 99999.

    net = pp.create_empty_network(f_hz=f_hz, sn_mva=baseMVA)

    # --- bus data -> create buses, sgen, load, shunt
    for i in range(len(ppc['bus'])):
        # create buses
        pp.create_bus(net,
                      name=int(ppc['bus'][i, 0]),
                      vn_kv=ppc['bus'][i, 9],
                      type="b",
                      zone=ppc['bus'][i, 6],
                      in_service=bool(ppc['bus'][i, 1] != 4),
                      max_vm_pu=ppc['bus'][i, 11],
                      min_vm_pu=ppc['bus'][i, 12])
        # create sgen, load
        if ppc['bus'][i, 2] > 0:
            pp.create_load(net,
                           i,
                           p_mw=ppc['bus'][i, 2],
                           q_mvar=ppc['bus'][i, 3],
                           controllable=False)
        elif ppc['bus'][i, 2] < 0:
            pp.create_sgen(net,
                           i,
                           p_mw=-ppc['bus'][i, 2],
                           q_mvar=-ppc['bus'][i, 3],
                           type="",
                           controllable=False)
        elif ppc['bus'][i, 3] != 0:
            pp.create_load(net,
                           i,
                           p_mw=ppc['bus'][i, 2],
                           q_mvar=ppc['bus'][i, 3],
                           controllable=False)
        # create shunt
        if ppc['bus'][i, 4] != 0 or ppc['bus'][i, 5] != 0:
            pp.create_shunt(net,
                            i,
                            p_mw=ppc['bus'][i, 4],
                            q_mvar=-ppc['bus'][i, 5])
    # unused data of ppc: Vm, Va (partwise: in ext_grid), zone

    # --- gen data -> create ext_grid, gen, sgen
    gen_lookup = DataFrame(nan,
                           columns=['element', 'element_type'],
                           index=range(len(ppc['gen'][:, 0])))
    # if in ppc is only one gen -> numpy initially uses one dim array -> change to two dim array
    if len(ppc["gen"].shape) == 1:
        ppc["gen"] = array(ppc["gen"], ndmin=2)
    for i in range(len(ppc['gen'][:, 0])):
        current_bus_type, current_bus_idx, same_bus_gen_idx, first_same_bus_in_service_gen_idx, \
            last_same_bus_in_service_gen_idx = _gen_bus_info(ppc, i)
        # create ext_grid
        if current_bus_type == 3:
            if i == first_same_bus_in_service_gen_idx:
                gen_lookup.element.loc[i] = pp.create_ext_grid(
                    net,
                    bus=current_bus_idx,
                    vm_pu=ppc['gen'][last_same_bus_in_service_gen_idx, 5],
                    va_degree=ppc['bus'][current_bus_idx, 8],
                    in_service=bool(ppc['gen'][i, 7] > 0),
                    max_p_mw=ppc['gen'][i, PMAX],
                    min_p_mw=ppc['gen'][i, PMIN],
                    max_q_mvar=ppc['gen'][i, QMAX],
                    min_q_mvar=ppc['gen'][i, QMIN])
                gen_lookup.element_type.loc[i] = 'ext_grid'
                if ppc['gen'][i, 4] > ppc['gen'][i, 3]:
                    logger.info(
                        'min_q_mvar of gen %d must be less than max_q_mvar but is not.'
                        % i)
                if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]:
                    logger.info(
                        'max_p_mw of gen %d must be less than min_p_mw but is not.'
                        % i)
            else:
                current_bus_type = 1
        # create gen
        elif current_bus_type == 2:
            if i == first_same_bus_in_service_gen_idx:
                gen_lookup.element.loc[i] = pp.create_gen(
                    net,
                    bus=current_bus_idx,
                    vm_pu=ppc['gen'][last_same_bus_in_service_gen_idx, 5],
                    p_mw=ppc['gen'][i, 1],
                    in_service=bool(ppc['gen'][i, 7] > 0),
                    controllable=True,
                    max_p_mw=ppc['gen'][i, PMAX],
                    min_p_mw=ppc['gen'][i, PMIN],
                    max_q_mvar=ppc['gen'][i, QMAX],
                    min_q_mvar=ppc['gen'][i, QMIN])
                gen_lookup.element_type.loc[i] = 'gen'
                if ppc['gen'][i, 1] < 0:
                    logger.info(
                        'p_mw of gen %d must be less than zero but is not.' %
                        i)
                if ppc['gen'][i, 4] > ppc['gen'][i, 3]:
                    logger.info(
                        'min_q_mvar of gen %d must be less than max_q_mvar but is not.'
                        % i)
                if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]:
                    logger.info(
                        'max_p_mw of gen %d must be less than min_p_mw but is not.'
                        % i)
            else:
                current_bus_type = 1
        # create sgen
        if current_bus_type == 1:
            gen_lookup.element.loc[i] = pp.create_sgen(
                net,
                bus=current_bus_idx,
                p_mw=ppc['gen'][i, 1],
                q_mvar=ppc['gen'][i, 2],
                type="",
                in_service=bool(ppc['gen'][i, 7] > 0),
                max_p_mw=ppc['gen'][i, PMAX],
                min_p_mw=ppc['gen'][i, PMIN],
                max_q_mvar=ppc['gen'][i, QMAX],
                min_q_mvar=ppc['gen'][i, QMIN],
                controllable=True)
            gen_lookup.element_type.loc[i] = 'sgen'
            if ppc['gen'][i, 1] < 0:
                logger.info(
                    'p_mw of sgen %d must be less than zero but is not.' % i)
            if ppc['gen'][i, 4] > ppc['gen'][i, 3]:
                logger.info(
                    'min_q_mvar of gen %d must be less than max_q_mvar but is not.'
                    % i)
            if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]:
                logger.info(
                    'max_p_mw of gen %d must be less than min_p_mw but is not.'
                    % i)
    # unused data of ppc: Vg (partwise: in ext_grid and gen), mBase, Pc1, Pc2, Qc1min, Qc1max,
    # Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30,ramp_q, apf

    # --- branch data -> create line, trafo
    for i in range(len(ppc['branch'])):
        from_bus = pp.get_element_index(net,
                                        'bus',
                                        name=int(ppc['branch'][i, 0]))
        to_bus = pp.get_element_index(net,
                                      'bus',
                                      name=int(ppc['branch'][i, 1]))

        from_vn_kv = ppc['bus'][from_bus, 9]
        to_vn_kv = ppc['bus'][to_bus, 9]
        if (from_vn_kv == to_vn_kv) & ((ppc['branch'][i, 8] == 0) | (ppc['branch'][i, 8] == 1)) & \
           (ppc['branch'][i, 9] == 0):  # create line
            Zni = ppc['bus'][to_bus, 9]**2 / baseMVA  # ohm
            max_i_ka = ppc['branch'][i, 5] / ppc['bus'][to_bus, 9] / sqrt(3)
            if max_i_ka == 0.0:
                max_i_ka = MAX_VAL
                logger.debug(
                    "ppc branch rateA is zero -> Using MAX_VAL instead to calculate "
                    + "maximum branch flow")
            pp.create_line_from_parameters(
                net,
                from_bus=from_bus,
                to_bus=to_bus,
                length_km=1,
                r_ohm_per_km=ppc['branch'][i, 2] * Zni,
                x_ohm_per_km=ppc['branch'][i, 3] * Zni,
                c_nf_per_km=ppc['branch'][i, 4] / Zni / omega * 1e9 / 2,
                max_i_ka=max_i_ka,
                type='ol',
                max_loading_percent=100,
                in_service=bool(ppc['branch'][i, 10]))

        else:  # create transformer
            if from_vn_kv >= to_vn_kv:
                hv_bus = from_bus
                vn_hv_kv = from_vn_kv
                lv_bus = to_bus
                vn_lv_kv = to_vn_kv
                tap_side = 'hv'
            else:
                hv_bus = to_bus
                vn_hv_kv = to_vn_kv
                lv_bus = from_bus
                vn_lv_kv = from_vn_kv
                tap_side = 'lv'
                if from_vn_kv == to_vn_kv:
                    logger.warning(
                        'The pypower branch %d (from_bus, to_bus)=(%d, %d) is considered'
                        ' as a transformer because of a ratio != 0 | 1 but it connects '
                        'the same voltage level', i, ppc['branch'][i, 0],
                        ppc['branch'][i, 1])
            rk = ppc['branch'][i, 2]
            xk = ppc['branch'][i, 3]
            zk = (rk**2 + xk**2)**0.5
            sn = ppc['branch'][i, 5]
            if sn == 0.0:
                sn = MAX_VAL
                logger.debug(
                    "ppc branch rateA is zero -> Using MAX_VAL instead to calculate "
                    + "apparent power")
            ratio_1 = 0 if ppc['branch'][i, 8] == 0 else (ppc['branch'][i, 8] -
                                                          1) * 100
            i0_percent = -ppc['branch'][i, 4] * 100 * baseMVA / sn
            if i0_percent < 0:
                logger.info(
                    'A transformer always behaves inductive consumpting but the '
                    'susceptance of pypower branch %d (from_bus, to_bus)=(%d, %d) is '
                    'positive.', i, ppc['branch'][i, 0], ppc['branch'][i, 1])

            pp.create_transformer_from_parameters(
                net,
                hv_bus=hv_bus,
                lv_bus=lv_bus,
                sn_mva=sn,
                vn_hv_kv=vn_hv_kv,
                vn_lv_kv=vn_lv_kv,
                vk_percent=sign(xk) * zk * sn * 100 / baseMVA,
                vkr_percent=rk * sn * 100 / baseMVA,
                max_loading_percent=100,
                pfe_kw=0,
                i0_percent=i0_percent,
                shift_degree=ppc['branch'][i, 9],
                tap_step_percent=abs(ratio_1) if ratio_1 else nan,
                tap_pos=sign(ratio_1) if ratio_1 else nan,
                tap_side=tap_side if ratio_1 else None,
                tap_neutral=0 if ratio_1 else nan)
    # unused data of ppc: rateB, rateC

    # --- gencost -> create polynomial_cost, piecewise_cost
    if 'gencost' in ppc:
        if len(ppc['gencost'].shape) == 1:
            # reshape gencost if only one gencost is given -> no indexError
            ppc['gencost'] = ppc['gencost'].reshape((1, -1))
        if ppc['gencost'].shape[0] <= gen_lookup.shape[0]:
            idx_p = range(ppc['gencost'].shape[0])
            idx_q = []
        elif ppc['gencost'].shape[0] > gen_lookup.shape[0]:
            idx_p = range(gen_lookup.shape[0])
            idx_q = range(gen_lookup.shape[0], ppc['gencost'].shape[0])
        if ppc['gencost'].shape[0] >= 2 * gen_lookup.shape[0]:
            idx_p = range(gen_lookup.shape[0])
            idx_q = range(gen_lookup.shape[0], 2 * gen_lookup.shape[0])
        for idx in idx_p:
            _create_costs(net, ppc, gen_lookup, 'p', idx)
        for idx in idx_q:
            _create_costs(net, ppc, gen_lookup, 'q', idx)

    # areas are unconverted

    if validate_conversion:
        logger.setLevel(logging.DEBUG)
        if not validate_from_ppc(ppc, net, **kwargs):
            logger.error("Validation failed.")

    return net
Exemplo n.º 19
0
def validate_from_ppc(
        ppc_net,
        net,
        pf_type="runpp",
        max_diff_values={
            "bus_vm_pu": 1e-6,
            "bus_va_degree": 1e-5,
            "branch_p_mw": 1e-6,
            "branch_q_mvar": 1e-6,
            "gen_p_mw": 1e-6,
            "gen_q_mvar": 1e-6
        },
        run=True):
    """
    This function validates the pypower case files to pandapower net structure conversion via a \
    comparison of loadflow calculation results. (Hence the opf cost conversion is not validated.)

    INPUT:

        **ppc_net** - The pypower case file, which must already contain the pypower powerflow
            results or pypower must be importable.

        **net** - The pandapower network.

    OPTIONAL:

        **pf_type** ("runpp", string) - Type of validated power flow. Possible are ("runpp",
            "rundcpp", "runopp", "rundcopp")

        **max_diff_values** - Dict of maximal allowed difference values. The keys must be
        'vm_pu', 'va_degree', 'p_branch_mw', 'q_branch_mvar', 'p_gen_mw' and 'q_gen_mvar' and
        the values floats.

        **run** (True, bool or list of two bools) - changing the value to False avoids trying to run
            (optimal) loadflows. Giving a list of two bools addresses first pypower and second
            pandapower.

    OUTPUT:

        **conversion_success** - conversion_success is returned as False if pypower or pandapower
        cannot calculate a powerflow or if the maximum difference values (max_diff_values )
        cannot be hold.

    EXAMPLE:

        import pandapower.converter as pc

        net = cv.from_ppc(ppc_net, f_hz=50)

        conversion_success = cv.validate_from_ppc(ppc_net, net)

    NOTE:

        The user has to take care that the loadflow results already are included in the provided \
        ppc_net or pypower is importable.
    """
    # check in case of optimal powerflow comparison whether cost information exist
    if "opp" in pf_type:
        if not (len(net.polynomial_cost) | len(net.piecewise_linear_cost)):
            if "gencost" in ppc_net:
                if not len(ppc_net["gencost"]):
                    logger.debug(
                        'ppc and pandapower net do not include cost information.'
                    )
                    return True
                else:
                    logger.error(
                        'The pandapower net does not include cost information.'
                    )
                    return False
            else:
                logger.debug(
                    'ppc and pandapower net do not include cost information.')
                return True

    # guarantee run parameter as list, for pypower and pandapower (optimal) powerflow run
    run = [run, run] if isinstance(run, bool) else run

    # --- check pypower powerflow success, if possible
    if pypower_import and run[0]:
        try:
            if pf_type == "runpp":
                ppc_net = runpf.runpf(ppc_net, ppopt)[0]
            elif pf_type == "rundcpp":
                ppc_net = rundcpf.rundcpf(ppc_net, ppopt)[0]
            elif pf_type == "runopp":
                ppc_net = runopf.runopf(ppc_net, ppopt)
            elif pf_type == "rundcopp":
                ppc_net = rundcopf.rundcopf(ppc_net, ppopt)
            else:
                raise ValueError("The pf_type %s is unknown" % pf_type)
        except:
            logger.debug("The pypower run did not work.")
    ppc_success = True
    if 'success' in ppc_net.keys():
        if ppc_net['success'] != 1:
            ppc_success = False
            logger.error(
                "The given ppc data indicates an unsuccessful pypower powerflow: "
                + "'ppc_net['success'] != 1'")
    if (ppc_net['branch'].shape[1] < 17):
        ppc_success = False
        logger.error(
            "The shape of given ppc data indicates missing pypower powerflow results."
        )

    # --- try to run a pandapower powerflow
    if run[1]:
        if pf_type == "runpp":
            try:
                pp.runpp(net,
                         init="dc",
                         calculate_voltage_angles=True,
                         trafo_model="pi")
            except pp.LoadflowNotConverged:
                try:
                    pp.runpp(net,
                             calculate_voltage_angles=True,
                             init="flat",
                             trafo_model="pi")
                except pp.LoadflowNotConverged:
                    try:
                        pp.runpp(net,
                                 trafo_model="pi",
                                 calculate_voltage_angles=False)
                        if "bus_va_degree" in max_diff_values.keys():
                            max_diff_values[
                                "bus_va_degree"] = 1e2 if max_diff_values[
                                    "bus_va_degree"] < 1e2 else max_diff_values[
                                        "bus_va_degree"]
                        logger.info("voltage_angles could be calculated.")
                    except pp.LoadflowNotConverged:
                        logger.error(
                            'The pandapower powerflow does not converge.')
        elif pf_type == "rundcpp":
            try:
                pp.rundcpp(net, trafo_model="pi")
            except pp.LoadflowNotConverged:
                logger.error('The pandapower dc powerflow does not converge.')
        elif pf_type == "runopp":
            try:
                pp.runopp(net, init="flat", calculate_voltage_angles=True)
            except pp.OPFNotConverged:
                try:
                    pp.runopp(net, init="pf", calculate_voltage_angles=True)
                except (pp.OPFNotConverged, pp.LoadflowNotConverged, KeyError):
                    try:
                        pp.runopp(net,
                                  init="flat",
                                  calculate_voltage_angles=False)
                        logger.info("voltage_angles could be calculated.")
                        if "bus_va_degree" in max_diff_values.keys():
                            max_diff_values[
                                "bus_va_degree"] = 1e2 if max_diff_values[
                                    "bus_va_degree"] < 1e2 else max_diff_values[
                                        "bus_va_degree"]
                    except pp.OPFNotConverged:
                        try:
                            pp.runopp(net,
                                      init="pf",
                                      calculate_voltage_angles=False)
                            if "bus_va_degree" in max_diff_values.keys():
                                max_diff_values[
                                    "bus_va_degree"] = 1e2 if max_diff_values[
                                        "bus_va_degree"] < 1e2 else max_diff_values[
                                            "bus_va_degree"]
                            logger.info("voltage_angles could be calculated.")
                        except (pp.OPFNotConverged, pp.LoadflowNotConverged,
                                KeyError):
                            logger.error(
                                'The pandapower optimal powerflow does not converge.'
                            )
        elif pf_type == "rundcopp":
            try:
                pp.rundcopp(net)
            except pp.LoadflowNotConverged:
                logger.error(
                    'The pandapower dc optimal powerflow does not converge.')
        else:
            raise ValueError("The pf_type %s is unknown" % pf_type)

    # --- prepare powerflow result comparison by reordering pp results as they are in ppc results
    if not ppc_success:
        return False
    if "opp" in pf_type:
        if not net.OPF_converged:
            return
    elif not net.converged:
        return False

    # --- store pypower powerflow results
    ppc_res = dict.fromkeys(ppc_elms)
    ppc_res["branch"] = ppc_net['branch'][:, 13:17]
    ppc_res["bus"] = ppc_net['bus'][:, 7:9]
    ppc_res["gen"] = ppc_net['gen'][:, 1:3]

    # --- pandapower bus result table
    pp_res = dict.fromkeys(ppc_elms)
    pp_res["bus"] = array(net.res_bus.sort_index()[['vm_pu', 'va_degree']])

    # --- pandapower gen result table
    pp_res["gen"] = zeros([1, 2])
    # consideration of parallel generators via storing how much generators have been considered
    # each node
    # if in ppc is only one gen -> numpy initially uses one dim array -> change to two dim array
    if len(ppc_net["gen"].shape) == 1:
        ppc_net["gen"] = array(ppc_net["gen"], ndmin=2)
    GENS = DataFrame(ppc_net['gen'][:, [0]].astype(int))
    GEN_uniq = GENS.drop_duplicates()
    already_used_gen = Series(zeros(GEN_uniq.shape[0]).astype(int),
                              index=[int(v) for v in GEN_uniq.values])
    change_q_compare = []
    for i, j in GENS.iterrows():
        current_bus_type, current_bus_idx, same_bus_gen_idx, first_same_bus_in_service_gen_idx, \
            last_same_bus_in_service_gen_idx = _gen_bus_info(ppc_net, i)
        if current_bus_type == 3 and i == first_same_bus_in_service_gen_idx:
            pp_res["gen"] = append(
                pp_res["gen"],
                array(net.res_ext_grid[net.ext_grid.bus == current_bus_idx][[
                    'p_mw', 'q_mvar'
                ]]).reshape((1, 2)), 0)
        elif current_bus_type == 2 and i == first_same_bus_in_service_gen_idx:
            pp_res["gen"] = append(
                pp_res["gen"],
                array(net.res_gen[net.gen.bus == current_bus_idx][[
                    'p_mw', 'q_mvar'
                ]]).reshape((1, 2)), 0)
        else:
            pp_res["gen"] = append(
                pp_res["gen"],
                array(net.res_sgen[net.sgen.bus == current_bus_idx][[
                    'p_mw', 'q_mvar'
                ]])[already_used_gen.at[int(j)]].reshape((1, 2)), 0)
            already_used_gen.at[int(j)] += 1
            change_q_compare += [int(j)]
    pp_res["gen"] = pp_res["gen"][1:, :]  # delete initial zero row

    # --- pandapower branch result table
    pp_res["branch"] = zeros([1, 4])
    # consideration of parallel branches via storing how often branches were considered
    # each node-to-node-connection
    try:
        init1 = concat([net.line.from_bus, net.line.to_bus], axis=1,
                       sort=True).drop_duplicates()
        init2 = concat([net.trafo.hv_bus, net.trafo.lv_bus], axis=1,
                       sort=True).drop_duplicates()
    except TypeError:
        # legacy pandas < 0.21
        init1 = concat([net.line.from_bus, net.line.to_bus],
                       axis=1).drop_duplicates()
        init2 = concat([net.trafo.hv_bus, net.trafo.lv_bus],
                       axis=1).drop_duplicates()
    init1['hv_bus'] = nan
    init1['lv_bus'] = nan
    init2['from_bus'] = nan
    init2['to_bus'] = nan
    try:
        already_used_branches = concat([init1, init2], axis=0, sort=True)
    except TypeError:
        # pandas < 0.21 legacy
        already_used_branches = concat([init1, init2], axis=0)
    already_used_branches['number'] = zeros(
        [already_used_branches.shape[0], 1]).astype(int)
    BRANCHES = DataFrame(ppc_net['branch'][:, [0, 1, 8, 9]])
    for i in BRANCHES.index:
        from_bus = pp.get_element_index(net,
                                        'bus',
                                        name=int(ppc_net['branch'][i, 0]))
        to_bus = pp.get_element_index(net,
                                      'bus',
                                      name=int(ppc_net['branch'][i, 1]))
        from_vn_kv = ppc_net['bus'][from_bus, 9]
        to_vn_kv = ppc_net['bus'][to_bus, 9]
        ratio = BRANCHES[2].at[i]
        angle = BRANCHES[3].at[i]
        # from line results
        if (from_vn_kv == to_vn_kv) & ((ratio == 0) |
                                       (ratio == 1)) & (angle == 0):
            pp_res["branch"] = append(
                pp_res["branch"],
                array(net.res_line[(net.line.from_bus == from_bus)
                                   & (net.line.to_bus == to_bus)][[
                                       'p_from_mw', 'q_from_mvar', 'p_to_mw',
                                       'q_to_mvar'
                                   ]])
                [int(already_used_branches.number.loc[
                    (already_used_branches.from_bus == from_bus) &
                    (already_used_branches.to_bus == to_bus)].values)].reshape(
                        1, 4), 0)
            already_used_branches.number.loc[
                (already_used_branches.from_bus == from_bus)
                & (already_used_branches.to_bus == to_bus)] += 1
        # from trafo results
        else:
            if from_vn_kv >= to_vn_kv:
                pp_res["branch"] = append(
                    pp_res["branch"],
                    array(net.res_trafo[(net.trafo.hv_bus == from_bus)
                                        & (net.trafo.lv_bus == to_bus)]
                          [['p_hv_mw', 'q_hv_mvar', 'p_lv_mw', 'q_lv_mvar'
                            ]])[int(already_used_branches.number.loc[
                                (already_used_branches.hv_bus == from_bus)
                                & (already_used_branches.lv_bus == to_bus)].
                                    values)].reshape(1, 4), 0)
                already_used_branches.number.loc[
                    (already_used_branches.hv_bus == from_bus)
                    & (already_used_branches.lv_bus == to_bus)] += 1
            else:  # switch hv-lv-connection of pypower connection buses
                pp_res["branch"] = append(
                    pp_res["branch"],
                    array(net.res_trafo[(net.trafo.hv_bus == to_bus)
                                        & (net.trafo.lv_bus == from_bus)]
                          [['p_lv_mw', 'q_lv_mvar', 'p_hv_mw', 'q_hv_mvar'
                            ]])[int(already_used_branches.number.loc[
                                (already_used_branches.hv_bus == to_bus)
                                & (already_used_branches.lv_bus == from_bus)].
                                    values)].reshape(1, 4), 0)
                already_used_branches.number.loc[
                    (already_used_branches.hv_bus == to_bus)
                    & (already_used_branches.lv_bus == from_bus)] += 1
    pp_res["branch"] = pp_res["branch"][1:, :]  # delete initial zero row

    # --- do the powerflow result comparison
    diff_res = dict.fromkeys(ppc_elms)
    diff_res["bus"] = ppc_res["bus"] - pp_res["bus"]
    diff_res["bus"][:, 1] -= diff_res["bus"][0, 1]  # remove va_degree offset
    diff_res["branch"] = ppc_res["branch"] - pp_res["branch"]
    diff_res["gen"] = ppc_res["gen"] - pp_res["gen"]
    # comparison of buses with several generator units only as q sum
    for i in GEN_uniq.loc[GEN_uniq[0].isin(change_q_compare)].index:
        next_is = GEN_uniq.index[GEN_uniq.index > i]
        if len(next_is) > 0:
            next_i = next_is[0]
        else:
            next_i = GENS.index[-1] + 1
        if (next_i - i) > 1:
            diff_res["gen"][i:next_i, 1] = sum(diff_res["gen"][i:next_i, 1])
    # logger info
    logger.debug(
        "Maximum voltage magnitude difference between pypower and pandapower: "
        "%.2e pu" % max_(abs(diff_res["bus"][:, 0])))
    logger.debug(
        "Maximum voltage angle difference between pypower and pandapower: "
        "%.2e degree" % max_(abs(diff_res["bus"][:, 1])))
    logger.debug(
        "Maximum branch flow active power difference between pypower and pandapower: "
        "%.2e MW" % max_(abs(diff_res["branch"][:, [0, 2]])))
    logger.debug(
        "Maximum branch flow reactive power difference between pypower and "
        "pandapower: %.2e MVAr" % max_(abs(diff_res["branch"][:, [1, 3]])))
    logger.debug(
        "Maximum active power generation difference between pypower and pandapower: "
        "%.2e MW" % max_(abs(diff_res["gen"][:, 0])))
    logger.debug(
        "Maximum reactive power generation difference between pypower and pandapower: "
        "%.2e MVAr" % max_(abs(diff_res["gen"][:, 1])))
    if _validate_diff_res(diff_res, {"bus_vm_pu": 1e-3, "bus_va_degree": 1e-3, "branch_p_mw": 1e-6,
                                     "branch_q_mvar": 1e-6}) and \
            (max_(abs(diff_res["gen"])) > 1e-1).any():
        logger.debug(
            "The active/reactive power generation difference possibly results "
            "because of a pypower error. Please validate "
            "the results via pypower loadflow."
        )  # this occurs e.g. at ppc case9
    # give a return
    if isinstance(max_diff_values, dict):
        return _validate_diff_res(diff_res, max_diff_values)
    else:
        logger.debug("'max_diff_values' must be a dict.")
def execute_my_script(EQ_file, SSH_file):
    #Next step is to create a tree by parsing the XML file referenced
    # We are here using ENTSO-E  model files used in Interoperability testing
    
    EQ_tree = ET.parse(EQ_file)
    SSH_tree = ET.parse(SSH_file)
    # We can access the root (raiz) of the tree and print it
    EQ_microgrid = EQ_tree.getroot()
    SSH_microgrid = SSH_tree.getroot()
    
    # To make working with the file easier, it may be useful to store the 
    # namespace identifiers in strings and reuse when you search for tags
        
    ns = {'cim':'http://iec.ch/TC57/2013/CIM-schema-cim16#',
          'entsoe':'http://entsoe.eu/CIM/SchemaExtension/3/1#',
          'rdf':'{http://www.w3.org/1999/02/22-rdf-syntax-ns#}'}
    
    
    #create an empty network 
    net = pp.create_empty_network()
    
    #to see al the elements in our system:
    EQ_tag=[]
    for eq in EQ_microgrid:
         if (ns['cim'] in eq.tag):
             equipment = eq.tag.replace("{"+ns['cim']+"}","")
             if equipment not in EQ_tag :
                 EQ_tag.append(equipment)
    print(EQ_tag)
    print("---------------------------------------------------------")
    
    # My goal here it's to create a dictionary that links voltage level with their respective ID
    
    # I want to to avoid repetition in the loop when finding the match voltage level of the equipment
    voltage_levels_dic = {}
    for voltage_level in EQ_microgrid.findall('cim:VoltageLevel', ns):
        voltage_name = float(voltage_level.find('cim:IdentifiedObject.name', ns).text)
        voltage_levels_dic[voltage_level.attrib.get(ns['rdf']+'ID')] = voltage_name
    print(voltage_levels_dic)
    
    # Create buses in the pandapower system from the XML file data adquired
    for bus in EQ_microgrid.findall('cim:BusbarSection', ns):
        # Extracting the name from the BusbarSection element
        bus_name = bus.find('cim:IdentifiedObject.name', ns).text
        # I the next line of code we want to obtain the Equipment.EquipmentContainer ID of each busbar section and take with it the corresponding bus 
        # voltage level relation that we have previously determined in the dictionary
        bus_voltage_level = voltage_levels_dic[bus.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')]
        pp.create_bus(net, bus_voltage_level, name=bus_name)
    
    print(net.bus)
    print("---------------------------------------------------------")
    
    # Create lines in the pandapower system from the XML file data adquired
    for line in EQ_microgrid.findall('cim:ACLineSegment', ns):
        #I want to get the ID of each line
        line_id = line.attrib.get(ns['rdf'] + 'ID')
        print (line_id)
        # next step will be retrieving the name of the line
        line_name =  line.find('cim:IdentifiedObject.name', ns).text
        print (line_name)
        # Now I want to get the length of the line
        line_length = float(line.find('cim:Conductor.length', ns).text)
        print (line_length)
        # get the resistance of the line
        line_resistance_per_km = float(line.find('cim:ACLineSegment.r', ns).text)/line_length
        # get the reactance of the line
        line_rectance_per_km = float(line.find('cim:ACLineSegment.x', ns).text)/line_length
        # I want to find the ID of the terminals where the line is connected to
        # Basically we want to know to wich 2 terminals each line is connected to in order to later define
        # from/to which buses the lines are connected to 
        for terminal in EQ_microgrid.findall('cim:Terminal', ns):
            line_Te_CE = terminal.find('cim:Terminal.ConductingEquipment', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
            line_sequence_number = terminal.find('cim:ACDCTerminal.sequenceNumber', ns).text
            if line_id == line_Te_CE: # We do this in order to select the terminals related to the lines
                if line_sequence_number == '1': 
                    #This is because for each line we have 2 terminals, the one with sequence number 1 and the other with seq number 2
                    # Gets the connectivity node ID from the terminals
                    line_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') 
                    # With this new for loop the objective is to find the ConnectivityNode associaton, in other words
                    # I want to obtain for each connectivitynode their corresponding id and container association
                    for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns):
                        if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN:
                            CN_id = CN.attrib.get(ns['rdf'] + 'ID')
                            CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                            # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer
                            # and the corresponding busbarsection 
                    for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):
                        if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container:
                            Line_Te1 = BusBar.find('cim:IdentifiedObject.name', ns).text
                elif line_sequence_number == '2':
                 # Gets the connectivity node ID from the terminals
                    line_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') 
                    # With this new for loop the objective is to find the ConnectivityNode associaton, in other words
                    # I want to obtain for each connectivitynode their corresponding id and container association
                    for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns):
                        if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN:
                            CN_id = CN.attrib.get(ns['rdf'] + 'ID')
                            CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                            # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer
                            # and the corresponding busbarsection 
                    for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):
                        if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container:
                            Line_Te2 = BusBar.find('cim:IdentifiedObject.name', ns).text
        Line_from_Bus = pp.get_element_index(net, "bus", Line_Te1)
        Line_to_Bus = pp.get_element_index(net, "bus", Line_Te2)
        pp.create_line(net, Line_from_Bus, Line_to_Bus, length_km=line_length,std_type='NAYY 4x50 SE', name=line_name)# parallel=hv_line.parallel)
    
    # show line table
    print(net.line)
    print("---------------------------------------------------------")
    
    
    # Create transformers in the pandapower system from the XML file data adquired
    for transformers in EQ_microgrid.findall('cim:PowerTransformer', ns):
        #I want to get the ID of each transformer
        transformer_id = transformers.attrib.get(ns['rdf'] + 'ID')
        # next step will be retrieving the name of the transformer
        transformers_name = transformers.find('cim:IdentifiedObject.name', ns).text
        print(transformers_name)
        # I want to find the ID of the terminals where the transformer is connected to
        for transformer_end in EQ_microgrid.findall('cim:PowerTransformerEnd', ns):
            transformer_end_id = transformer_end.find('cim:PowerTransformerEnd.PowerTransformer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
            # Find the side of the power transformer
            if transformer_id == transformer_end_id:
                transformer_end_number = transformer_end.find('cim:TransformerEnd.endNumber', ns).text
                # I want to find the value of the TransformerEnd.endNumber because it will give you the information about if 
                # it is the HV(=1) or LV(=2) 
                print(transformer_end_number)
                
                if transformer_end_number == '1':
                # As we did previously for the lines we use did if in order to create 2 paths, one will define the
                # parameters of HV side and the other the parameters of the LV side
                # I am taking the information of the transformer, Power rating of the transformer 
                # The parameters are taking on the  HV(=1) side because is where the data about r,x is stored at the XML file
                    transformer_S = float(transformer_end.find('cim:PowerTransformerEnd.ratedS', ns).text)
                    transformer_hv_kv = float(transformer_end.find('cim:PowerTransformerEnd.ratedU', ns).text)
                    transformer_r = float(transformer_end.find('cim:PowerTransformerEnd.r', ns).text)
                    transformer_x = float(transformer_end.find('cim:PowerTransformerEnd.x', ns).text)
                    transformer_z = (transformer_r ** 2 + transformer_x ** 2) ** (1/2)
                    # I am going to neglect the iron losses, the open loop losses, shift degree
                    # Find the terminal the transformer end is connected to
                    transformer_end_terminal = transformer_end.find('cim:TransformerEnd.Terminal', ns).attrib.get(ns['rdf'] + 'resource').replace('#','')
                    for terminal in EQ_microgrid.findall('cim:Terminal', ns):
                        terminal_id = terminal.attrib.get(ns['rdf'] + 'ID')
                        if terminal_id == transformer_end_terminal:
                            # Take the connectivity node's ID from the terminal
                            transformer_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                            # With this new for loop the objective is to find the ConnectivityNode associaton, in other words
                            # I want to obtain for each connectivitynode their corresponding id and container association
                            for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns):
                                if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN:
                                    transformer_CN_id = CN.attrib.get(ns['rdf'] + 'ID')
                                    transformer_CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                            # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer
                            # and the corresponding busbarsection 
                            for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):
                                if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container:
                                    transformer_Te1 = BusBar.find('cim:IdentifiedObject.name', ns).text
                # Now we want to do the same for the LV side                    
                elif transformer_end_number == '2':
                    transformer_lv_kv = float(transformer_end.find('cim:PowerTransformerEnd.ratedU', ns).text)
                    # Find the terminal the transformer end is connected to
                    transformer_end_terminal = transformer_end.find('cim:TransformerEnd.Terminal', ns).attrib.get(ns['rdf'] + 'resource').replace('#','')
                    for terminal in EQ_microgrid.findall('cim:Terminal', ns):
                        terminal_id = terminal.attrib.get(ns['rdf'] + 'ID')
                        if terminal_id == transformer_end_terminal:
                            # Take the connectivity node's ID from the terminal
                            transformer_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                            # With this new for loop the objective is to find the ConnectivityNode associaton, in other words
                            # I want to obtain for each connectivitynode their corresponding id and container association
                            for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns):
                                if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN:
                                    transformer_CN_id = CN.attrib.get(ns['rdf'] + 'ID')
                                    transformer_CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                            # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer
                            # and the corresponding busbarsection 
                            for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):
                                if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container:
                                    transformer_Te2 = BusBar.find('cim:IdentifiedObject.name', ns).text
                                    
        hv_bus = pp.get_element_index(net, "bus", transformer_Te1)
        lv_bus = pp.get_element_index(net, "bus", transformer_Te2)
        pp.create_transformer_from_parameters(net, hv_bus, lv_bus, sn_mva=transformer_S, vn_hv_kv=transformer_hv_kv, vn_lv_kv=transformer_lv_kv, vkr_percent=0.06,
                                          vk_percent=8, pfe_kw=0, i0_percent=0, tp_pos=0, shift_degree=0, name=transformers_name)
    
    print(net.trafo) # show trafo table  
    print("---------------------------------------------------------")
    
    # Create Loads in the pandapower system from the XML file (SSH) data adquired
    # In order to do this, firs we will take the name and ID of the loads from the EQ file, afterwards we will use this
    # Id that we have obtained before to look for its corresponding P & Q data stored in the SSH file
    
    for load in EQ_microgrid.findall('cim:EnergyConsumer', ns):
        #I want to get the ID of each load
        eq_load_id = load.attrib.get(ns['rdf'] + 'ID')
        # next step will be retrieving the name of the load
        load_name = load.find('cim:IdentifiedObject.name', ns).text
        print(load_name)
        for ssh_load in SSH_microgrid.findall('cim:EnergyConsumer', ns):
            ssh_load_id = ssh_load.attrib.get(ns['rdf'] + 'about').replace('#', '')
            print(ssh_load_id)
            if ssh_load_id == eq_load_id:
                P_load = float(ssh_load.find('cim:EnergyConsumer.p', ns).text)
                Q_load = float(ssh_load.find('cim:EnergyConsumer.q', ns).text)
        # After we got the P & Q for each load, now I want to find the terminal associated to each load (from the EQ file again)
        for terminal in EQ_microgrid.findall('cim:Terminal', ns):
            load_Te_CE = terminal.find('cim:Terminal.ConductingEquipment', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
            if eq_load_id == load_Te_CE: # We do this in order to select the terminals related to the loads
                load_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') 
                # With this new for loop the objective is to find the ConnectivityNode associaton, in other words
                # I want to obtain for each connectivitynode their corresponding id and container association
                for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns):
                        if CN.attrib.get(ns['rdf'] + 'ID') == load_Te_CN:
                            CN_id = CN.attrib.get(ns['rdf'] + 'ID')
                            CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                            # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer
                            # and the corresponding busbarsection 
                for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):
                    if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container:
                        Load_Te = BusBar.find('cim:IdentifiedObject.name', ns).text
                        
        bus_idx = pp.get_element_index(net, "bus", Load_Te)
        pp.create_load(net, bus_idx, p_mw=P_load, q_mvar=Q_load, name=load_name)
    
    # show load table
    print(net.load)
    print("---------------------------------------------------------")
    
    # Create generators in pandapower, 
    for generator in EQ_microgrid.findall('cim:GeneratingUnit', ns):
        generator_id = generator.attrib.get(ns['rdf'] + 'ID')
        generator_name = generator.find('cim:IdentifiedObject.name', ns).text
        generator_initial_P = float(generator.find('cim:GeneratingUnit.initialP', ns).text)
        # Looking for the SynchronousMachine related to the generator unit
        for synch_machine in  EQ_microgrid.findall('cim:SynchronousMachine', ns):
            synch_machine_id = synch_machine.attrib.get(ns['rdf'] + 'ID')
            if synch_machine.find('cim:RotatingMachine.GeneratingUnit', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == generator_id:
                synch_machine_ratedU = float(synch_machine.find('cim:RotatingMachine.ratedU', ns).text)
                # print(synch_machine_ratedU)
                synch_machine_id = synch_machine.attrib.get(ns['rdf'] + 'ID')
                synch_machine_equip_cont = synch_machine.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
        
        for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):
            BusBar_equip_cont = BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
            if BusBar_equip_cont == synch_machine_equip_cont:
                generator_busbar = BusBar.find('cim:IdentifiedObject.name', ns).text
                bus_voltage = voltage_levels_dic[BusBar_equip_cont]
               # print(bus_voltage)
                vm_pu = synch_machine_ratedU / bus_voltage
                print(vm_pu)
        pp.create_gen(net, pp.get_element_index(net, "bus", generator_busbar), generator_initial_P, vm_pu, name=generator_name)    
        # vm_pu=1.0 this is because there is no extra info about vm_pu in the xml file. Thus, as the rated voltage 
        # of the synch.machine is exactly the same as the bus which it is connected
        # Find the terminal the generator is connected to
    print(net.gen)
    print("---------------------------------------------------------")
    
    # Create shunt capacitors in pandapower. 
    # To define shunt in pandapower we need: the bus that is connected to, p_mw=0, q_mvar, name.
    for shunt in EQ_microgrid.findall('cim:LinearShuntCompensator', ns):
        shunt_id = shunt.attrib.get(ns['rdf'] + 'ID')
        shunt_name = shunt.find('cim:IdentifiedObject.name', ns).text
        shunt_b = float(shunt.find('cim:LinearShuntCompensator.bPerSection', ns).text)
        shunt_nom_U = float(shunt.find('cim:ShuntCompensator.nomU', ns).text)
        # In a shunt capacitor, Q = b*(Unom^2) because g = 0
        shunt_Q = shunt_b*(shunt_nom_U**2)
        shunt_equip_cont = shunt.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
        for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):
            BusBar_equip_cont = BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
            if BusBar_equip_cont == shunt_equip_cont:
                shunt_busbar = BusBar.find('cim:IdentifiedObject.name', ns).text
        
        pp.create_shunt(net, pp.get_element_index(net, "bus", shunt_busbar), p_mw=0, q_mvar=shunt_Q, name=shunt_name)
    
            
    print(net.shunt)
    print("---------------------------------------------------------")
    
    # Create breakers in pandapower. 
    for breaker in EQ_microgrid.findall('cim:Breaker', ns):
        breaker_id = breaker.attrib.get(ns['rdf'] + 'ID')
        breaker_name = breaker.find('cim:IdentifiedObject.name', ns).text
        breaker_position = breaker.find('cim:Switch.normalOpen', ns).text
        # Breaker position in the EQ.xml file determines if the sitch is open(=TRUE), but for pandapower
        # the parameteres examines if the switch is closed(=FALSE), thi is why we need to create
        # an if condition to readjust this as we want
        if breaker_position == 'false':
            breaker_position = True
        elif breaker_position == 'true':
            breaker_position = False
        # I want to find the ID of the terminals where the breaker is connected to
        # Basically we want to know to wich 2 terminals each breaker is connected to in order to later define
        # from/to which buses the breaker are connected to 
        for terminal in EQ_microgrid.findall('cim:Terminal', ns):
            breaker_Te_CE = terminal.find('cim:Terminal.ConductingEquipment', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
            breaker_sequence_number = terminal.find('cim:ACDCTerminal.sequenceNumber', ns).text
            if breaker_id == breaker_Te_CE:
                if breaker_sequence_number == '1':
                # Take the connectivity node's ID from the terminal
                    breaker_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                    # With this new for loop the objective is to find the ConnectivityNode associaton, in other words
                    # I want to obtain for each connectivitynode their corresponding id and container association
                    for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns):
                        if CN.attrib.get(ns['rdf'] + 'ID') == breaker_Te_CN:
                            CN_id = CN.attrib.get(ns['rdf'] + 'ID')
                            CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                     # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer
                     # and the corresponding busbarsection 
                    for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):                    
                        if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container:
                            breaker_Te1 = BusBar.find('cim:IdentifiedObject.name', ns).text
                            print(breaker_Te1)
                elif breaker_sequence_number == '2':
                    # Gets the connectivity node ID from the terminals
                    breaker_Te_CN = terminal.find('cim:Terminal.ConnectivityNode', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') 
                    # With this new for loop the objective is to find the ConnectivityNode associaton, in other words
                    # I want to obtain for each connectivitynode their corresponding id and container association
                    for CN in EQ_microgrid.findall('cim:ConnectivityNode', ns):
                        if CN.attrib.get(ns['rdf'] + 'ID') == line_Te_CN:
                            CN_id = CN.attrib.get(ns['rdf'] + 'ID')
                            CN_container = CN.find('cim:ConnectivityNode.ConnectivityNodeContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '')
                            # I want now to stablish a connection between the ConnectivityNode.ConnectivityNodeContainer
                            # and the corresponding busbarsection 
                    for BusBar in EQ_microgrid.findall('cim:BusbarSection', ns):
                        if BusBar.find('cim:Equipment.EquipmentContainer', ns).attrib.get(ns['rdf'] + 'resource').replace('#', '') == CN_container:
                            breaker_Te2 = BusBar.find('cim:IdentifiedObject.name', ns).text
                            print(breaker_Te2)
                            print("---------------------------------------------------------")
    
        from_bus = pp.get_element_index(net, "bus", breaker_Te1)
        to_bus = pp.get_element_index(net, "bus", breaker_Te2)
        pp.create_switch(net, from_bus, to_bus, et='b', closed=breaker_position, type='CB', name=breaker_name)
    
    print(net.switch)
    
    plot.to_html(net, 'plot_system.html')
    #plot.simple_plot(net, respect_switches=False, line_width=1.0, bus_size=1.0, ext_grid_size=1.0, trafo_size=1.0, plot_loads=False, plot_sgens=False, load_size=1.0, sgen_size=1.0, switch_size=2.0, 
     #                switch_distance=1.0, plot_line_switches=False, scale_size=True, bus_color='b', line_color='grey', trafo_color='k', ext_grid_color='y', switch_color='k', library='igraph', show_plot=True, ax=None)               
                    
                    
#execute_my_script('MicroGridTestConfiguration_T1_BE_EQ_V2.xml', 'MicroGridTestConfiguration_T1_BE_SSH_V2.xml')                 
Exemplo n.º 21
0
def from_ppc(ppc, f_hz=50, validate_conversion=False):
    """
    This function converts pypower case files to pandapower net structure.

    INPUT:

        **ppc** - The pypower case file.

    OPTIONAL:

        **f_hz** - The frequency of the network.

    OUTPUT:

        **net**

    EXAMPLE:

        import pandapower.converter as pc

        from pypower import case4gs

        ppc_net = case4gs.case4gs()

        pp_net = cv.from_ppc(ppc_net, f_hz=60)

    """
    # --- catch common failures
    if Series(ppc['bus'][:, 9] <= 0).any():
        logger.info('There are false baseKV given in the pypower case file.')

    # --- general_parameters
    baseMVA = ppc['baseMVA']  # MVA
    omega = pi * f_hz  # 1/s
    MAX_VAL = 99999.

    net = pp.create_empty_network(f_hz=f_hz)

    # --- bus data -> create buses, sgen, load, shunt
    for i in range(len(ppc['bus'])):
        # create buses
        pp.create_bus(net,
                      name=int(ppc['bus'][i, 0]),
                      vn_kv=ppc['bus'][i, 9],
                      type="b",
                      zone=ppc['bus'][i, 6],
                      in_service=bool(ppc['bus'][i, 1] != 4),
                      max_vm_pu=ppc['bus'][i, 11],
                      min_vm_pu=ppc['bus'][i, 12])
        # create sgen, load
        if ppc['bus'][i, 2] > 0:
            pp.create_load(net,
                           i,
                           p_kw=ppc['bus'][i, 2] * 1e3,
                           q_kvar=ppc['bus'][i, 3] * 1e3)
        elif ppc['bus'][i, 2] < 0:
            pp.create_sgen(net,
                           i,
                           p_kw=ppc['bus'][i, 2] * 1e3,
                           q_kvar=ppc['bus'][i, 3] * 1e3,
                           type="")
        elif ppc['bus'][i, 3] != 0:
            pp.create_load(net,
                           i,
                           p_kw=ppc['bus'][i, 2] * 1e3,
                           q_kvar=ppc['bus'][i, 3] * 1e3)
        # create shunt
        if ppc['bus'][i, 4] != 0 or ppc['bus'][i, 5] != 0:
            pp.create_shunt(net,
                            i,
                            p_kw=ppc['bus'][i, 4] * 1e3,
                            q_kvar=-ppc['bus'][i, 5] * 1e3)
    # unused data of ppc: Vm, Va (partwise: in ext_grid), zone

    # --- gen data -> create ext_grid, gen, sgen
    for i in range(len(ppc['gen'])):
        # if in ppc is only one gen -> numpy initially uses one dim array -> change to two dim array
        if len(ppc["gen"].shape) == 1:
            ppc["gen"] = array(ppc["gen"], ndmin=2)
        current_bus_idx = pp.get_element_index(net,
                                               'bus',
                                               name=int(ppc['gen'][i, 0]))
        current_bus_type = int(ppc['bus'][current_bus_idx, 1])
        # create ext_grid
        if current_bus_type == 3:
            if len(pp.get_connected_elements(net, 'ext_grid',
                                             current_bus_idx)) > 0:
                logger.info('At bus %d an ext_grid already exists. ' %
                            current_bus_idx +
                            'Because of that generator %d ' % i +
                            'is converted not as an ext_grid but as a sgen')
                current_bus_type = 1
            else:
                pp.create_ext_grid(net,
                                   bus=current_bus_idx,
                                   vm_pu=ppc['gen'][i, 5],
                                   va_degree=ppc['bus'][current_bus_idx, 8],
                                   in_service=bool(ppc['gen'][i, 7] > 0),
                                   max_p_kw=-ppc['gen'][i, 9] * 1e3,
                                   min_p_kw=-ppc['gen'][i, 8] * 1e3,
                                   max_q_kvar=ppc['gen'][i, 3] * 1e3,
                                   min_q_kvar=ppc['gen'][i, 4] * 1e3)
                if ppc['gen'][i, 4] > ppc['gen'][i, 3]:
                    logger.info(
                        'min_q_kvar of gen %d must be less than max_q_kvar but is not.'
                        % i)
                if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]:
                    logger.info(
                        'max_p_kw of gen %d must be less than min_p_kw but is not.'
                        % i)
        # create gen
        elif current_bus_type == 2:
            pp.create_gen(net,
                          bus=current_bus_idx,
                          vm_pu=ppc['gen'][i, 5],
                          p_kw=-ppc['gen'][i, 1] * 1e3,
                          in_service=bool(ppc['gen'][i, 7] > 0),
                          max_p_kw=-ppc['gen'][i, 9] * 1e3,
                          min_p_kw=-ppc['gen'][i, 8] * 1e3,
                          max_q_kvar=ppc['gen'][i, 3] * 1e3,
                          min_q_kvar=ppc['gen'][i, 4] * 1e3,
                          controllable=True)
            if ppc['gen'][i, 4] > ppc['gen'][i, 3]:
                logger.info(
                    'min_q_kvar of gen %d must be less than max_q_kvar but is not.'
                    % i)
            if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]:
                logger.info(
                    'max_p_kw of gen %d must be less than min_p_kw but is not.'
                    % i)
        # create sgen
        if current_bus_type == 1:
            pp.create_sgen(net,
                           bus=current_bus_idx,
                           p_kw=-ppc['gen'][i, 1] * 1e3,
                           q_kvar=-ppc['gen'][i, 2] * 1e3,
                           type="",
                           in_service=bool(ppc['gen'][i, 7] > 0),
                           max_p_kw=-ppc['gen'][i, 9] * 1e3,
                           min_p_kw=-ppc['gen'][i, 8] * 1e3,
                           max_q_kvar=ppc['gen'][i, 3] * 1e3,
                           min_q_kvar=ppc['gen'][i, 4] * 1e3,
                           controllable=True)
            if ppc['gen'][i, 4] > ppc['gen'][i, 3]:
                logger.info(
                    'min_q_kvar of gen %d must be less than max_q_kvar but is not.'
                    % i)
            if -ppc['gen'][i, 9] < -ppc['gen'][i, 8]:
                logger.info(
                    'max_p_kw of gen %d must be less than min_p_kw but is not.'
                    % i)
    # unused data of ppc: Vg (partwise: in ext_grid and gen), mBase, Pc1, Pc2, Qc1min, Qc1max,
    # Qc2min, Qc2max, ramp_agc, ramp_10, ramp_30,ramp_q, apf

    # --- branch data -> create line, trafo
    for i in range(len(ppc['branch'])):
        from_bus = pp.get_element_index(net,
                                        'bus',
                                        name=int(ppc['branch'][i, 0]))
        to_bus = pp.get_element_index(net,
                                      'bus',
                                      name=int(ppc['branch'][i, 1]))

        from_vn_kv = ppc['bus'][from_bus, 9]
        to_vn_kv = ppc['bus'][to_bus, 9]
        if (from_vn_kv == to_vn_kv) & ((ppc['branch'][i, 8] == 0) | (ppc['branch'][i, 8] == 1)) & \
           (ppc['branch'][i, 9] == 0):
            Zni = ppc['bus'][to_bus, 9]**2 / baseMVA  # ohm
            max_i_ka = ppc['branch'][i, 5] / ppc['bus'][to_bus, 9]
            if max_i_ka == 0.0:
                max_i_ka = MAX_VAL
                logger.debug(
                    "ppc branch rateA is zero -> Using MAX_VAL instead to calculate "
                    + "maximum branch flow")
            pp.create_line_from_parameters(
                net,
                from_bus=from_bus,
                to_bus=to_bus,
                length_km=1,
                r_ohm_per_km=ppc['branch'][i, 2] * Zni,
                x_ohm_per_km=ppc['branch'][i, 3] * Zni,
                c_nf_per_km=ppc['branch'][i, 4] / Zni / omega * 1e9 / 2,
                max_i_ka=max_i_ka,
                type='ol',
                in_service=bool(ppc['branch'][i, 10]))

        else:
            if from_vn_kv >= to_vn_kv:
                hv_bus = from_bus
                vn_hv_kv = from_vn_kv
                lv_bus = to_bus
                vn_lv_kv = to_vn_kv
                tp_side = 'hv'
            else:
                hv_bus = to_bus
                vn_hv_kv = to_vn_kv
                lv_bus = from_bus
                vn_lv_kv = from_vn_kv
                tp_side = 'lv'
                if from_vn_kv == to_vn_kv:
                    logger.warning(
                        'The pypower branch %d (from_bus, to_bus)=(%d, %d) is considered'
                        ' as a transformer because of a ratio != 0 | 1 but it connects '
                        'the same voltage level', i, ppc['branch'][i, 0],
                        ppc['branch'][i, 1])
            rk = ppc['branch'][i, 2]
            xk = ppc['branch'][i, 3]
            zk = (rk**2 + xk**2)**0.5
            sn = ppc['branch'][i, 5] * 1e3
            if sn == 0.0:
                sn = MAX_VAL
                logger.debug(
                    "ppc branch rateA is zero -> Using MAX_VAL instead to calculate "
                    + "apparent power")
            ratio_1 = 0 if ppc['branch'][i, 8] == 0 else (ppc['branch'][i, 8] -
                                                          1) * 100
            i0_percent = -ppc['branch'][i, 4] * 100 * baseMVA * 1e3 / sn
            if i0_percent < 0:
                logger.info(
                    'A transformer always behaves inductive consumpting but the '
                    'susceptance of pypower branch %d (from_bus, to_bus)=(%d, %d) is '
                    'positive.', i, ppc['branch'][i, 0], ppc['branch'][i, 1])

            pp.create_transformer_from_parameters(
                net,
                hv_bus=hv_bus,
                lv_bus=lv_bus,
                sn_kva=sn,
                vn_hv_kv=vn_hv_kv,
                vn_lv_kv=vn_lv_kv,
                vsc_percent=zk * sn / 1e3,
                vscr_percent=rk * sn / 1e3,
                pfe_kw=0,
                i0_percent=i0_percent,
                shift_degree=ppc['branch'][i, 9],
                tp_st_percent=abs(ratio_1) if ratio_1 else nan,
                tp_pos=sign(ratio_1) if ratio_1 else nan,
                tp_side=tp_side if ratio_1 else None,
                tp_mid=0 if ratio_1 else nan)
    # unused data of ppc: rateB, rateC

    # ToDo: gencost, areas are currently unconverted
    if validate_conversion:
        # set logger level to debug
        logger.setLevel(10)
        if not validate_from_ppc(ppc, net):
            logger.error("Validation failed.")

    return net
Exemplo n.º 22
0
def example_multivoltage():
    """
    Returns the multivoltage example network from the pandapower tutorials.

    OUTPUT:
        net - multivoltage example network

    EXAMPLE:

    >>> import pandapower.networks
    >>> net = pandapower.networks.example_multivoltage()

    """
    net = pp.create_empty_network()

    # --- Busses

    # HV
    # Double busbar
    pp.create_bus(net, name='Double Busbar 1', vn_kv=380, type='b')
    pp.create_bus(net, name='Double Busbar 2', vn_kv=380, type='b')

    for i in range(10):
        pp.create_bus(net, name='Bus DB T%s' % i, vn_kv=380, type='n')

    for i in range(1, 5):
        pp.create_bus(net, name='Bus DB %s' % i, vn_kv=380, type='n')

    # Single busbar
    pp.create_bus(net, name='Single Busbar', vn_kv=110, type='b')

    for i in range(1, 6):
        pp.create_bus(net, name='Bus SB %s' % i, vn_kv=110, type='n')

    for i in range(1, 6):
        for j in [1, 2]:
            pp.create_bus(net,
                          name='Bus SB T%s.%s' % (i, j),
                          vn_kv=110,
                          type='n')

    # Remaining
    for i in range(1, 5):
        pp.create_bus(net, name='Bus HV%s' % i, vn_kv=110, type='n')

    # MV
    pp.create_bus(net, name='Bus MV0 20kV', vn_kv=20, type='n')

    for i in range(8):
        pp.create_bus(net, name='Bus MV%s' % i, vn_kv=10, type='n')

    # LV
    pp.create_bus(net, name='Bus LV0', vn_kv=0.4, type='n')

    for i in range(1, 6):
        pp.create_bus(net, name='Bus LV1.%s' % i, vn_kv=0.4, type='m')

    for i in range(1, 5):
        pp.create_bus(net, name='Bus LV2.%s' % i, vn_kv=0.4, type='m')

    pp.create_bus(net, name='Bus LV2.2.1', vn_kv=0.4, type='m')
    pp.create_bus(net, name='Bus LV2.2.2', vn_kv=0.4, type='m')

    # --- Lines

    # HV
    hv_lines = pd.DataFrame()
    hv_lines['line_name'] = ['HV Line%s' % i for i in range(1, 7)]
    hv_lines['from_bus'] = [
        'Bus SB 2', 'Bus HV1', 'Bus HV2', 'Bus HV1', 'Bus HV3', 'Bus SB 3'
    ]
    hv_lines['to_bus'] = [
        'Bus HV1', 'Bus HV2', 'Bus HV4', 'Bus HV4', 'Bus HV4', 'Bus HV3'
    ]
    hv_lines['std_type'] = '184-AL1/30-ST1A 110.0'
    hv_lines['length'] = [30, 20, 30, 15, 25, 30]
    hv_lines['parallel'] = [1, 1, 1, 1, 1, 2]

    for _, hv_line in hv_lines.iterrows():
        from_bus = pp.get_element_index(net, "bus", hv_line.from_bus)
        to_bus = pp.get_element_index(net, "bus", hv_line.to_bus)
        pp.create_line(net,
                       from_bus,
                       to_bus,
                       length_km=hv_line.length,
                       std_type=hv_line.std_type,
                       name=hv_line.line_name,
                       parallel=hv_line.parallel)

    # MV
    mv_lines = pd.DataFrame()
    mv_lines['line_name'] = ['MV Line%s' % i for i in range(1, 9)]
    mv_lines['from_bus'] = ['Bus MV%s' % i for i in list(range(7)) + [0]]
    mv_lines['to_bus'] = ['Bus MV%s' % i for i in list(range(1, 8)) + [7]]
    mv_lines['length'] = 1.5
    mv_lines['std_type'] = 'NA2XS2Y 1x185 RM/25 12/20 kV'

    for _, mv_line in mv_lines.iterrows():
        from_bus = pp.get_element_index(net, "bus", mv_line.from_bus)
        to_bus = pp.get_element_index(net, "bus", mv_line.to_bus)
        pp.create_line(net,
                       from_bus,
                       to_bus,
                       length_km=mv_line.length,
                       std_type=mv_line.std_type,
                       name=mv_line.line_name)

    # LV
    lv_lines = pd.DataFrame()
    lv_line_idx = [
        '1.1', '1.2', '1.3', '1.4', '1.6', '2.1', '2.2', '2.3', '2.4', '2.2.1',
        '2.2.2'
    ]
    lv_lines['line_name'] = ['LV Line%s' % i for i in lv_line_idx]
    lv_line_idx = [
        '0', '1.1', '1.2', '1.3', '1.4', '0', '2.1', '2.2', '2.3', '2.2',
        '2.2.1'
    ]
    lv_lines['from_bus'] = ['Bus LV%s' % i for i in lv_line_idx]
    lv_line_idx = [
        '1.1', '1.2', '1.3', '1.4', '1.5', '2.1', '2.2', '2.3', '2.4', '2.2.1',
        '2.2.2'
    ]
    lv_lines['to_bus'] = ['Bus LV%s' % i for i in lv_line_idx]
    lv_lines['length'] = [0.08] * 5 + [0.12] * 6
    lv_lines['std_type'] = ['NAYY 4x120 SE'] * 7 + ['15-AL1/3-ST1A 0.4'] * 4

    for _, lv_line in lv_lines.iterrows():
        from_bus = pp.get_element_index(net, "bus", lv_line.from_bus)
        to_bus = pp.get_element_index(net, "bus", lv_line.to_bus)
        pp.create_line(net,
                       from_bus,
                       to_bus,
                       length_km=lv_line.length,
                       std_type=lv_line.std_type,
                       name=lv_line.line_name)

    # --- Transformer

    hv_bus = pp.get_element_index(net, "bus", "Bus DB 2")
    lv_bus = pp.get_element_index(net, "bus", "Bus SB 1")
    pp.create_transformer_from_parameters(net,
                                          hv_bus,
                                          lv_bus,
                                          sn_kva=300000,
                                          vn_hv_kv=380,
                                          vn_lv_kv=110,
                                          vscr_percent=0.06,
                                          vsc_percent=8,
                                          pfe_kw=0,
                                          i0_percent=0,
                                          tp_pos=0,
                                          shift_degree=0,
                                          name='EHV-HV-Trafo')

    hv_bus = pp.get_element_index(net, "bus", "Bus MV4")
    lv_bus = pp.get_element_index(net, "bus", "Bus LV0")
    pp.create_transformer_from_parameters(net,
                                          hv_bus,
                                          lv_bus,
                                          sn_kva=400,
                                          vn_hv_kv=10,
                                          vn_lv_kv=0.4,
                                          vscr_percent=1.325,
                                          vsc_percent=4,
                                          pfe_kw=0.95,
                                          i0_percent=0.2375,
                                          tp_side="hv",
                                          tp_mid=0,
                                          tp_min=-2,
                                          tp_max=2,
                                          tp_st_percent=2.5,
                                          tp_pos=0,
                                          shift_degree=150,
                                          name='MV-LV-Trafo')

    # Trafo3w
    hv_bus = pp.get_element_index(net, "bus", "Bus HV2")
    mv_bus = pp.get_element_index(net, "bus", "Bus MV0 20kV")
    lv_bus = pp.get_element_index(net, "bus", "Bus MV0")
    pp.create_transformer3w_from_parameters(net,
                                            hv_bus,
                                            mv_bus,
                                            lv_bus,
                                            vn_hv_kv=110,
                                            vn_mv_kv=20,
                                            vn_lv_kv=10,
                                            sn_hv_kva=40000,
                                            sn_mv_kva=15000,
                                            sn_lv_kva=25000,
                                            vsc_hv_percent=10.1,
                                            vsc_mv_percent=10.1,
                                            vsc_lv_percent=10.1,
                                            vscr_hv_percent=0.266667,
                                            vscr_mv_percent=0.033333,
                                            vscr_lv_percent=0.04,
                                            pfe_kw=0,
                                            i0_percent=0,
                                            shift_mv_degree=30,
                                            shift_lv_degree=30,
                                            tp_side="hv",
                                            tp_mid=0,
                                            tp_min=-8,
                                            tp_max=8,
                                            tp_st_percent=1.25,
                                            tp_pos=0,
                                            name='HV-MV-MV-Trafo')

    # --- Static generators

    # HV
    pp.create_sgen(net,
                   pp.get_element_index(net, "bus", 'Bus SB 5'),
                   p_kw=-20000,
                   q_kvar=-4000,
                   sn_kva=45000,
                   type='WP',
                   name='Wind Park')

    # MV
    mv_sgens = pd.DataFrame()
    mv_sgens['sgen_name'] = [
        'Biogas plant', 'Further MV Generator', 'Industry Generator', 'PV Park'
    ]
    mv_sgens['bus'] = ['Bus MV6', 'Bus MV0', 'Bus MV0 20kV', 'Bus MV5']
    mv_sgens['p'] = [-500, -500, -15000, -2000]
    mv_sgens['q'] = [0, -50, -3000, -100]
    mv_sgens['sn'] = [750, 1000, 20000, 5000]
    mv_sgens['type'] = ['SGEN', 'SGEN', 'SGEN', 'PV']

    for _, sgen in mv_sgens.iterrows():
        bus_idx = pp.get_element_index(net, "bus", sgen.bus)
        pp.create_sgen(net,
                       bus_idx,
                       p_kw=sgen.p,
                       q_kvar=sgen.q,
                       sn_kva=sgen.sn,
                       type=sgen.type,
                       name=sgen.sgen_name)

    # LV
    lv_sgens = pd.DataFrame()
    lv_sgens['sgen_name'] = ['PV'] + ['PV(%s)' % i for i in range(1, 6)]
    lv_sgens['bus'] = [
        'Bus LV%s' % i for i in ['1.1', '1.3', '2.3', '2.4', '2.2.1', '2.2.2']
    ]
    lv_sgens['p'] = [-6, -5, -5, -5, -5, -5]
    lv_sgens['q'] = 0
    lv_sgens['sn'] = [12, 10, 10, 10, 10, 10]
    lv_sgens['type'] = 'PV'

    for _, sgen in lv_sgens.iterrows():
        bus_idx = pp.get_element_index(net, "bus", sgen.bus)
        pp.create_sgen(net,
                       bus_idx,
                       p_kw=sgen.p,
                       q_kvar=sgen.q,
                       sn_kva=sgen.sn,
                       type=sgen.type,
                       name=sgen.sgen_name)

    # --- Loads

    # HV
    hv_loads = pd.DataFrame()
    hv_loads['load_name'] = ['MV Net %s' % i for i in range(5)]
    hv_loads['bus'] = ['Bus SB 4', 'Bus HV1', 'Bus HV2', 'Bus HV3', 'Bus HV4']
    hv_loads['p'] = 38000
    hv_loads['q'] = 6000

    for _, load in hv_loads.iterrows():
        bus_idx = pp.get_element_index(net, "bus", load.bus)
        pp.create_load(net,
                       bus_idx,
                       p_kw=load.p,
                       q_kvar=load.q,
                       name=load.load_name)

    # MV
    mv_loads = pd.DataFrame()
    mv_loads['load_name'] = ['Further MV-Rings', 'Industry Load'
                             ] + ['LV Net %s' % i for i in [1, 2, 3, 5, 6, 7]]
    mv_loads['bus'] = ['Bus MV0', 'Bus MV0 20kV'
                       ] + ['Bus MV%s' % i for i in [1, 2, 3, 5, 6, 7]]
    mv_loads['p'] = [6000, 18000, 400, 400, 400, 400, 400, 400]
    mv_loads['q'] = [2000, 4000, 100, 60, 60, 60, 60, 60]

    for _, load in mv_loads.iterrows():
        bus_idx = pp.get_element_index(net, "bus", load.bus)
        pp.create_load(net,
                       bus_idx,
                       p_kw=load.p,
                       q_kvar=load.q,
                       name=load.load_name)

    # LV
    lv_loads = pd.DataFrame()
    idx = ['', '(1)', '(2)', '(3)', '(4)', '(5)']
    lv_loads['load_name'] = ['Further LV-Feeders Load'] + [
        'Residential Load%s' % i for i in idx[0:5]
    ] + ['Rural Load%s' % i for i in idx[0:6]]
    lv_loads['bus'] = [
        'Bus LV%s' % i for i in [
            '0', '1.1', '1.2', '1.3', '1.4', '1.5', '2.1', '2.2', '2.3', '2.4',
            '2.2.1', '2.2.2'
        ]
    ]
    lv_loads['p'] = [100] + [10] * 11
    lv_loads['q'] = [10] + [3] * 11

    for _, load in lv_loads.iterrows():
        bus_idx = pp.get_element_index(net, "bus", load.bus)
        pp.create_load(net,
                       bus_idx,
                       p_kw=load.p,
                       q_kvar=load.q,
                       name=load.load_name)

    # --- Other

    # Shunt
    pp.create_shunt(net,
                    pp.get_element_index(net, "bus", 'Bus HV1'),
                    p_kw=0,
                    q_kvar=-960,
                    name='Shunt')

    # ExtGrids
    pp.create_ext_grid(net,
                       pp.get_element_index(net, "bus", 'Double Busbar 1'),
                       vm_pu=1.03,
                       va_degree=0,
                       name='External grid',
                       s_sc_max_mva=10000,
                       rx_max=0.1,
                       rx_min=0.1)
    # Gen
    pp.create_gen(net,
                  pp.get_element_index(net, "bus", 'Bus HV4'),
                  vm_pu=1.03,
                  p_kw=-1e5,
                  name='Gas turbine')

    # Impedance
    pp.create_impedance(net,
                        pp.get_element_index(net, "bus", 'Bus HV3'),
                        pp.get_element_index(net, "bus", 'Bus HV1'),
                        rft_pu=0.074873,
                        xft_pu=0.198872,
                        sn_kva=100000,
                        name='Impedance')

    # xwards
    pp.create_xward(net,
                    pp.get_element_index(net, "bus", 'Bus HV3'),
                    ps_kw=23942,
                    qs_kvar=-12241.87,
                    pz_kw=2814.571,
                    qz_kvar=0,
                    r_ohm=0,
                    x_ohm=12.18951,
                    vm_pu=1.02616,
                    name='XWard 1')
    pp.create_xward(net,
                    pp.get_element_index(net, "bus", 'Bus HV1'),
                    ps_kw=3776,
                    qs_kvar=-7769.979,
                    pz_kw=9174.917,
                    qz_kvar=0,
                    r_ohm=0,
                    x_ohm=50.56217,
                    vm_pu=1.024001,
                    name='XWard 2')

    # --- Switches

    # HV
    # Bus-bus switches
    hv_bus_sw = pd.DataFrame()
    hv_bus_sw['bus_name'] = ['DB DS%s' % i for i in range(14)] + \
                            ['DB CB%s' % i for i in range(5)] + \
                            ['SB DS%s.%s' % (i, j) for i in range(1, 6) for j in range(1, 3)] + \
                            ['SB CB%s' % i for i in range(1, 6)]
    hv_bus_sw['from_bus'] = ['Double Busbar %s' % i for i in [2, 1, 2, 1, 2, 1, 2, 1, 2, 1]] + \
                            ['Bus DB T%s' % i for i in [2, 4, 6, 8, 0, 3, 5, 7, 9]] + \
                            ['Bus SB T1.1', 'Single Busbar', 'Bus SB T2.1', 'Single Busbar',
                             'Bus SB T3.1', 'Single Busbar', 'Bus SB T4.1', 'Single Busbar',
                             'Bus SB T5.1', 'Single Busbar'] + \
                            ['Bus SB T%s.2' % i for i in range(1, 6)]
    hv_bus_sw['to_bus'] = ['Bus DB %s' % i for i in
                           ['T0', 'T1', 'T3', 'T3', 'T5', 'T5', 'T7', 'T7', 'T9', 'T9',
                            '1', '2', '3', '4', 'T1', 'T2', 'T4', 'T6', 'T8']] + \
                          ['Bus SB %s' % i for i in
                           ['1', 'T1.2', '2', 'T2.2', '3', 'T3.2', '4', 'T4.2', '5', 'T5.2']] + \
                          ['Bus SB T%s.1' % i for i in range(1, 6)]
    hv_bus_sw['type'] = ['DS'] * 14 + ['CB'] * 5 + ['DS'] * 10 + ['CB'] * 5
    hv_bus_sw['et'] = 'b'
    hv_bus_sw['closed'] = [
        bool(i)
        for i in [1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1] +
        [1] * 15
    ]

    for _, switch in hv_bus_sw.iterrows():
        from_bus = pp.get_element_index(net, "bus", switch.from_bus)
        to_bus = pp.get_element_index(net, "bus", switch.to_bus)
        pp.create_switch(net,
                         from_bus,
                         to_bus,
                         et=switch.et,
                         closed=switch.closed,
                         type=switch.type,
                         name=switch.bus_name)

    # Bus-Line switches
    hv_buses = net.bus[(net.bus.vn_kv == 380) | (net.bus.vn_kv == 110)].index
    hv_ls = net.line[(net.line.from_bus.isin(hv_buses))
                     & (net.line.to_bus.isin(hv_buses))]
    for _, line in hv_ls.iterrows():
        for bus in [line.from_bus, line.to_bus]:
            pp.create_switch(net,
                             bus,
                             line.name,
                             et='l',
                             closed=True,
                             type='LBS',
                             name='Switch %s - %s' %
                             (net.bus.name.at[bus], line['name']))

    # MV
    # Bus-line switches
    mv_buses = net.bus[(net.bus.vn_kv == 10) | (net.bus.vn_kv == 20)].index
    mv_ls = net.line[(net.line.from_bus.isin(mv_buses))
                     & (net.line.to_bus.isin(mv_buses))]
    for _, line in mv_ls.iterrows():
        for bus in [line.from_bus, line.to_bus]:
            pp.create_switch(net,
                             bus,
                             line.name,
                             et='l',
                             closed=True,
                             type='LBS',
                             name='Switch %s - %s' %
                             (net.bus.name.at[bus], line['name']))

    open_switch_id = net.switch[(
        net.switch.name == 'Switch Bus MV5 - MV Line5')].index
    net.switch.closed.loc[open_switch_id] = False

    # LV
    # Bus-line switches
    lv_buses = net.bus[net.bus.vn_kv == 0.4].index
    lv_ls = net.line[(net.line.from_bus.isin(lv_buses))
                     & (net.line.to_bus.isin(lv_buses))]
    for _, line in lv_ls.iterrows():
        for bus in [line.from_bus, line.to_bus]:
            pp.create_switch(net,
                             bus,
                             line.name,
                             et='l',
                             closed=True,
                             type='LBS',
                             name='Switch %s - %s' %
                             (net.bus.name.at[bus], line['name']))

    # Trafoswitches
    # HV
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus DB 2'),
                     pp.get_element_index(net, "trafo", 'EHV-HV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch DB2 - EHV-HV-Trafo')
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus SB 1'),
                     pp.get_element_index(net, "trafo", 'EHV-HV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch SB1 - EHV-HV-Trafo')
    # LV
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus MV4'),
                     pp.get_element_index(net, "trafo", 'MV-LV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch MV4 - MV-LV-Trafo')
    pp.create_switch(net,
                     pp.get_element_index(net, "bus", 'Bus LV0'),
                     pp.get_element_index(net, "trafo", 'MV-LV-Trafo'),
                     et='t',
                     closed=True,
                     type='LBS',
                     name='Switch LV0 - MV-LV-Trafo')

    # --- Powerflow

    # run power flow and generate result tables
    pp.runpp(net, init='dc', calculate_voltage_angles=True, Numba=False)

    return net
Exemplo n.º 23
0
for elementa in range(len(BreakerValue)):
    for elementb in range(len(NodeValue)):
        for elementc in range(len(NodeValue[elementb].conn_eqp)):
            if BreakerValue[elementa].name == NodeValue[elementb].conn_eqp[
                    elementc]:
                CB_element.append(NodeValue[elementb].name)
'''
Now I have the list of circuit breaker connected to particular nodes, since there are nine Circuit breakers 
in the system, and each has two connections/sides so to get the values from the list, each increment will 
show one connected to particular circuit breaker, each increment indentifies the buses connected to that end.
'''
for elementa in range(len(BreakerValue)):
    name = BreakerValue[elementa].name

    if elementa == 0:
        connection1 = pp.get_element_index(net, "bus", CB_element[elementa])

        connection2 = pp.get_element_index(net, "bus",
                                           CB_element[elementa + 1])

    if elementa == 1:
        connection1 = pp.get_element_index(net, "bus",
                                           CB_element[elementa + 1])

        connection2 = pp.get_element_index(net, "bus",
                                           CB_element[elementa + 2])

    if elementa == 2:
        connection1 = pp.get_element_index(net, "bus",
                                           CB_element[elementa + 2])
Exemplo n.º 24
0
def sim_request(data):
    is_three_phase = utils.get_or_error("3phase", data)
    elements_dict = utils.get_or_error("elements", data)
    buses = {} # Used for matching bus UUIDs to index

    def process_potential_bus(key, value):
        """ Inner method for processing a positional argument that could be a bus
            This function checks if the value is in the bus keys. This should never cause issues so long as UUID's aren't used for
            any other purpose except for bus identification and as long as there are no UUID collisions. Both of those cases seem
            exceptionally unlikely, so this should work fine.
        """
        if value in buses.keys():
            return buses[value]
        else:
            return value

    bus_list = [(uuid, element) for uuid, element in elements_dict.items() if utils.get_or_error("etype", element) == "bus"]
    element_list = [(uuid, element) for uuid, element in elements_dict.items() if utils.get_or_error("etype", element) != "bus" and utils.get_or_error("etype", element) != "switch"]
    switch_list = [(uuid, element) for uuid, element in elements_dict.items() if utils.get_or_error("etype", element) == "switch"]

    net = pp.create_empty_network()

    for uuid, bus in bus_list:
        element_type = "bus"
        req_props = utils.required_props[element_type]
        positional_args = [ value for key, value in bus.items() if key in req_props ]
        optional_args = { key: value for key, value in bus.items() if (not key in req_props) and (not key == "etype")}
        index = pp.create_bus(net, *positional_args, **optional_args, name=uuid)
        buses[uuid] = index
    
    for uuid, element in element_list:
        element_type = utils.get_or_error("etype", element)
        req_props = utils.required_props[element_type]
        positional_args = [process_potential_bus(key, value) for key, value in element.items() if key in req_props]
        optional_args = { key: value for key, value in element.items() if (not key in req_props) and (not key == "etype")}
        
        if element_type == "load":
            pp.create_load(net, *positional_args, **optional_args, name=uuid)
        elif element_type == "gen":
            pp.create_gen(net, *positional_args, **optional_args, name=uuid)
        elif element_type == "ext_grid":
            pp.create_ext_grid(net, *positional_args, **optional_args, name=uuid)
        elif element_type == "line":
            pp.create_line(net, *positional_args, *optional_args, name=uuid)
        elif element_type == "trafo":
            pp.create_transformer_from_parameters(net, *positional_args, **optional_args, name=uuid)
        elif element_type == "storage":
            pp.create_storage(net, *positional_args, **optional_args, name=uuid)
        else:
            raise InvalidError(f"Element type {element_type} is invalid or not implemented!")

    for uuid, switch in switch_list:
        element_type = "switch"
        req_props = utils.required_props[element_type]
        positional_args = [process_potential_bus(key, value) for key, value in element.items() if key in req_props]
        optional_args = { key: value for key, value in element.items() if (not key in req_props) and (not key == "etype")}
        et = positional_args[2]
        if et == "b":
            pass # This is handled by process_potential_buses
        if et == "l":
            positional_args[1] = pp.get_element_index(net, "line", positional_args[1])
        elif et == "t":
            positional_args[1] = pp.get_element_index(net, "trafo", positional_args[1])
        elif et == "t3":
            positional_args[1] = pp.get_element_index(net, "trafo3w", positional_args[1])
        else:
            raise InvalidError(f"Invalid element type {et}. Must be b,l,t, or t3.")
        pp.create_switch(net, *positional_args, **optional_args, name=uuid)
            
    try:
        if is_three_phase:
            pp.runpp_3ph(net)
        else:
            pp.runpp(net)
    except LoadflowNotConverged:
        report = pp.diagnostic(net, report_style="compact", warnings_only=True)
        raise ConvError("Load flow did not converge.")
    except (KeyError, ValueError) as e:
        raise PPError(str(e))
    except Exception as e:
        raise PPError("Unknown exception has occured: " + str(e))

    message = {}
    message["status"] = "SIM_RESULT"
    results = {}

    for uuid,element in elements_dict.items():
        element_type = elements_dict[uuid]["etype"]
        if element_type == "switch": continue
        net["res_" + element_type] = net["res_" + element_type].fillna(0)
        results[uuid] = {}
        results[uuid]["etype"] = element_type
        index = pp.get_element_index(net, element_type, uuid, exact_match=True)
        results[uuid].update(net["res_" + element_type].iloc[index].to_dict())

    message["elements"] = results
    return json.dumps(message)
# Remaining buses
for i in range(1, 5):
    pp.create_bus(net, name='Bus HV%s' % i, vn_kv=110, type='n')

# show bustable
net.bus

hv_lines = pd.read_csv('example_advanced/hv_lines.csv',
                       sep=';',
                       header=0,
                       decimal=',')
hv_lines

# create lines
for _, hv_line in hv_lines.iterrows():
    from_bus = pp.get_element_index(net, "bus", hv_line.from_bus)
    to_bus = pp.get_element_index(net, "bus", hv_line.to_bus)
    pp.create_line(net,
                   from_bus,
                   to_bus,
                   length_km=hv_line.length,
                   std_type=hv_line.std_type,
                   name=hv_line.line_name,
                   parallel=hv_line.parallel)

# show line table
net.line

hv_bus = pp.get_element_index(net, "bus", "Bus DB 2")
lv_bus = pp.get_element_index(net, "bus", "Bus SB 1")
pp.create_transformer_from_parameters(net,
Exemplo n.º 26
0
for voltage in base_voltage_list:
    baseVol = voltage.ID
    base_voltage = voltage.name
    base_volt_dict[baseVol] = base_voltage

# BUS
for bus in busbar_list:
    pp.create_bus(net, name=bus.name, vn_kv=bus.voltage, type="b")

# Transformer
for transformer in power_transformer_list:
    bus_list, way_terminals = find_attached_busbar(transformer)
    for bus, wt in zip(bus_list, way_terminals):
        if terminal_volt_dict[wt].end_number == '1':
            bus_high = bus
            hv_bus = pp.get_element_index(net, "bus", bus.name)
            vn = terminal_volt_dict[wt].baseVol
            vn_hv_kv = base_volt_dict[vn[1:]]
            sn_mva = terminal_volt_dict[wt].s
        elif terminal_volt_dict[wt].end_number == '2':
            bus_low = bus
            lv_bus = pp.get_element_index(net, "bus", bus.name)
            vn = terminal_volt_dict[wt].baseVol
            vn_lv_kv = base_volt_dict[vn[1:]]

    pp.create_transformer_from_parameters(net,
                                          name=transformer.name,
                                          hv_bus=hv_bus,
                                          lv_bus=lv_bus,
                                          sn_mva=sn_mva,
                                          vn_hv_kv=vn_hv_kv,
def create_network():
    network = pp.create_empty_network()

    sn_vn_transformer_data = {
        "sn_mva": 1,
        "vn_hv_kv": 20,
        "vn_lv_kv": 0.4,
        "vk_percent": 5,
        "vkr_percent": 1.1,
        "pfe_kw": 1.95,
        "i0_percent": 0.27,
        "shift_degree": 0
    }
    pp.create_std_type(network,
                       sn_vn_transformer_data,
                       "SN/NN 1MVA",
                       element='trafo')

    slack_bus = pp.create_bus(network, vn_kv=110, name="Slack Bus")

    busNodes = []
    lowVoltageBusNodes = []

    pp.create_ext_grid(network,
                       bus=slack_bus,
                       vm_pu=1.01,
                       name="Grid Connection")
    mediumVoltageBusNode = pp.create_bus(network,
                                         vn_kv=20,
                                         name="MV slack side")
    pp.create_transformer(network,
                          hv_bus=slack_bus,
                          lv_bus=mediumVoltageBusNode,
                          std_type="40 MVA 110/20 kV",
                          name="VN/SN Transformer")

    for i in range(0, 100):
        busNodes.append(
            pp.create_bus(network, vn_kv=20, name="Bus_" + str(i + 1)))
        lowVoltageBusNodes.append(
            pp.create_bus(network,
                          vn_kv=0.4,
                          name="LowVoltageBus_" + str(i + 1)))
        pp.create_load(network,
                       bus=lowVoltageBusNodes[i],
                       p_mw=0.14,
                       q_mvar=0.05,
                       name="Load_" + str(i + 1))
        pp.create_transformer(network,
                              hv_bus=busNodes[i],
                              lv_bus=lowVoltageBusNodes[i],
                              std_type="SN/NN 1MVA",
                              name="Transformer_" + str(i + 1))

    pp.create_line(network,
                   from_bus=mediumVoltageBusNode,
                   to_bus=busNodes[0],
                   length_km=0.2,
                   name="Line_0",
                   std_type="NA2XS2Y 1x150 RM/25 12/20 kV")

    for i in range(0, 99):
        pp.create_line(network,
                       from_bus=busNodes[i],
                       to_bus=busNodes[i + 1],
                       length_km=0.6,
                       name="Line_" + str(i + 1),
                       std_type="NA2XS2Y 1x150 RM/25 12/20 kV")

    # Add capacitors with regulating switches
    pp.create_bus(network, vn_kv=20, name="Bus_Cap1")
    pp.create_switch(network,
                     pp.get_element_index(network, "bus", 'Bus_13'),
                     pp.get_element_index(network, "bus", 'Bus_Cap1'),
                     et="b",
                     closed=False,
                     type="LBS",
                     name="CapSwitch1")
    pp.create_shunt_as_capacitor(network,
                                 pp.get_element_index(network, "bus",
                                                      'Bus_Cap1'),
                                 0.125,
                                 0,
                                 name="Cap1")

    pp.create_bus(network, vn_kv=20, name="Bus_Cap2")
    pp.create_switch(network,
                     pp.get_element_index(network, "bus", 'Bus_39'),
                     pp.get_element_index(network, "bus", 'Bus_Cap2'),
                     et="b",
                     closed=False,
                     type="LBS",
                     name="CapSwitch2")
    pp.create_shunt_as_capacitor(network,
                                 pp.get_element_index(network, "bus",
                                                      'Bus_Cap2'),
                                 0.8,
                                 0,
                                 name="Cap2")

    pp.create_bus(network, vn_kv=20, name="Bus_Cap3")
    pp.create_switch(network,
                     pp.get_element_index(network, "bus", 'Bus_85'),
                     pp.get_element_index(network, "bus", 'Bus_Cap3'),
                     et="b",
                     closed=False,
                     type="LBS",
                     name="CapSwitch3")
    pp.create_shunt_as_capacitor(network,
                                 pp.get_element_index(network, "bus",
                                                      'Bus_Cap3'),
                                 0.125,
                                 0,
                                 name="Cap3")

    pp.create_bus(network, vn_kv=20, name="Bus_Cap4")
    pp.create_switch(network,
                     pp.get_element_index(network, "bus", 'Bus_28'),
                     pp.get_element_index(network, "bus", 'Bus_Cap4'),
                     et="b",
                     closed=False,
                     type="LBS",
                     name="CapSwitch4")
    pp.create_shunt_as_capacitor(network,
                                 pp.get_element_index(network, "bus",
                                                      'Bus_Cap4'),
                                 3,
                                 0,
                                 name="Cap4")

    pp.create_bus(network, vn_kv=20, name="Bus_Cap5")
    pp.create_switch(network,
                     pp.get_element_index(network, "bus", 'Bus_59'),
                     pp.get_element_index(network, "bus", 'Bus_Cap5'),
                     et="b",
                     closed=False,
                     type="LBS",
                     name="CapSwitch5")
    pp.create_shunt_as_capacitor(network,
                                 pp.get_element_index(network, "bus",
                                                      'Bus_Cap5'),
                                 0.25,
                                 0,
                                 name="Cap5")

    pp.create_bus(network, vn_kv=20, name="Bus_Cap6")
    pp.create_switch(network,
                     pp.get_element_index(network, "bus", 'Bus_70'),
                     pp.get_element_index(network, "bus", 'Bus_Cap6'),
                     et="b",
                     closed=False,
                     type="LBS",
                     name="CapSwitch6")
    pp.create_shunt_as_capacitor(network,
                                 pp.get_element_index(network, "bus",
                                                      'Bus_Cap6'),
                                 0.8,
                                 0,
                                 name="Cap6")

    pp.create_bus(network, vn_kv=20, name="Bus_Cap7")
    pp.create_switch(network,
                     pp.get_element_index(network, "bus", 'Bus_48'),
                     pp.get_element_index(network, "bus", 'Bus_Cap7'),
                     et="b",
                     closed=False,
                     type="LBS",
                     name="CapSwitch7")
    pp.create_shunt_as_capacitor(network,
                                 pp.get_element_index(network, "bus",
                                                      'Bus_Cap7'),
                                 0.25,
                                 0,
                                 name="Cap7")

    pp.create_bus(network, vn_kv=20, name="Bus_Cap8")
    pp.create_switch(network,
                     pp.get_element_index(network, "bus", 'Bus_95'),
                     pp.get_element_index(network, "bus", 'Bus_Cap8'),
                     et="b",
                     closed=False,
                     type="LBS",
                     name="CapSwitch8")
    pp.create_shunt_as_capacitor(network,
                                 pp.get_element_index(network, "bus",
                                                      'Bus_Cap8'),
                                 0.25,
                                 0,
                                 name="Cap8")

    return network
Exemplo n.º 28
0
def get_res_value(net, table, name, res_col):
    obj = pp.get_element_index(net, table, name)
    df = getattr(net, "res_" + table)
    return df.loc[obj, res_col]
Exemplo n.º 29
0
def validate_from_ppc(
    ppc_net,
    pp_net,
    max_diff_values={
        "vm_pu": 1e-6,
        "va_degree": 1e-5,
        "p_branch_kw": 1e-3,
        "q_branch_kvar": 1e-3,
        "p_gen_kw": 1e-3,
        "q_gen_kvar": 1e-3
    }):
    """
    This function validates the pypower case files to pandapower net structure conversion via a \
    comparison of loadflow calculations.

    INPUT:

        **ppc_net** - The pypower case file.

        **pp_net** - The pandapower network.

    OPTIONAL:

        **max_diff_values** - Dict of maximal allowed difference values. The keys must be
            'vm_pu', 'va_degree', 'p_branch_kw', 'q_branch_kvar', 'p_gen_kw' and 'q_gen_kvar' and
            the values floats.

    OUTPUT:

        **conversion_success** - conversion_success is returned as False if pypower or pandapower
            cannot calculate a power flow or if the maximum difference values (max_diff_values )
            cannot be hold.

    EXAMPLE:

        import pandapower.converter as pc

        from pypower import case4gs

        ppc_net = case4gs.case4gs()

        pp_net = cv.from_ppc(ppc_net, f_hz=60)

        cv.validate_from_ppc(ppc_net, pp_net)
    """
    # --- run a pypower power flow without print output
    ppopt = ppoption.ppoption(VERBOSE=0, OUT_ALL=0)
    ppc_res = runpf.runpf(ppc_net, ppopt)[0]

    # --- store pypower power flow results
    ppc_res_branch = ppc_res['branch'][:, 13:17]
    ppc_res_bus = ppc_res['bus'][:, 7:9]
    ppc_res_gen = ppc_res['gen'][:, 1:3]

    # --- try to run a pandapower power flow
    try:
        pp.runpp(pp_net,
                 init="dc",
                 calculate_voltage_angles=True,
                 trafo_model="pi")
    except:
        try:
            pp.runpp(pp_net,
                     calculate_voltage_angles=True,
                     init="flat",
                     trafo_model="pi")
        except:
            try:
                pp.runpp(pp_net, trafo_model="pi")
            except:
                if (ppc_res['success'] == 1) & (~pp_net.converged):
                    logger.error(
                        'The validation of ppc conversion fails because the pandapower net'
                        ' power flow does not converge.')
                elif (ppc_res['success'] != 1) & (pp_net.converged):
                    logger.error(
                        'The validation of ppc conversion fails because the power flow of '
                        'the pypower case does not converge.')
                elif (ppc_res['success'] != 1) & (~pp_net.converged):
                    logger.error(
                        'The power flow of both, the pypower case and the pandapower net, '
                        'do not converge.')
                return False

    # --- prepare power flow result comparison by reordering pp results as they are in ppc results
    if (ppc_res['success'] == 1) & (pp_net.converged):
        # --- pandapower bus result table
        pp_res_bus = array(pp_net.res_bus[['vm_pu', 'va_degree']])

        # --- pandapower gen result table
        pp_res_gen = zeros([1, 2])
        # consideration of parallel generators via storing how much generators have been considered
        # each node
        already_used_gen = Series(zeros([pp_net.bus.shape[0]]),
                                  index=pp_net.bus.index).astype(int)
        GENS = DataFrame(ppc_res['gen'][:, [0]].astype(int))
        change_q_compare = []
        for i, j in GENS.iterrows():
            current_bus_idx = pp.get_element_index(pp_net, 'bus', name=j[0])
            current_bus_type = int(ppc_res['bus'][current_bus_idx, 1])
            # ext_grid
            if current_bus_type == 3:
                if already_used_gen.at[current_bus_idx] == 0:
                    pp_res_gen = append(
                        pp_res_gen,
                        array(pp_net.res_ext_grid[
                            pp_net.ext_grid.bus == current_bus_idx][[
                                'p_kw', 'q_kvar'
                            ]])[already_used_gen.at[current_bus_idx]].reshape(
                                (1, 2)), 0)
                    already_used_gen.at[current_bus_idx] += 1
                else:
                    pp_res_gen = append(
                        pp_res_gen,
                        array(pp_net.res_sgen[
                            pp_net.sgen.bus == current_bus_idx][[
                                'p_kw', 'q_kvar'
                            ]])[already_used_gen.at[current_bus_idx] -
                                1].reshape((1, 2)), 0)
                    already_used_gen.at[current_bus_idx] += 1
                    change_q_compare += [j[0]]
            # gen
            elif current_bus_type == 2:
                pp_res_gen = append(
                    pp_res_gen,
                    array(pp_net.res_gen[pp_net.gen.bus == current_bus_idx][[
                        'p_kw', 'q_kvar'
                    ]])[already_used_gen.at[current_bus_idx]].reshape((1, 2)),
                    0)
                if already_used_gen.at[current_bus_idx] > 0:
                    change_q_compare += [j[0]]
                already_used_gen.at[current_bus_idx] += 1
            # sgen
            elif current_bus_type == 1:
                pp_res_gen = append(
                    pp_res_gen,
                    array(pp_net.res_sgen[pp_net.sgen.bus == current_bus_idx][[
                        'p_kw', 'q_kvar'
                    ]])[already_used_gen.at[current_bus_idx]].reshape((1, 2)),
                    0)
                already_used_gen.at[current_bus_idx] += 1
        pp_res_gen = pp_res_gen[1:, :]  # delete initial zero row

        # --- pandapower branch result table
        pp_res_branch = zeros([1, 4])
        # consideration of parallel branches via storing how much branches have been considered
        # each node-to-node-connection
        init1 = concat([pp_net.line.from_bus, pp_net.line.to_bus],
                       axis=1).drop_duplicates()
        init2 = concat([pp_net.trafo.hv_bus, pp_net.trafo.lv_bus],
                       axis=1).drop_duplicates()
        init1['hv_bus'] = nan
        init1['lv_bus'] = nan
        init2['from_bus'] = nan
        init2['to_bus'] = nan
        already_used_branches = concat([init1, init2], axis=0)
        already_used_branches['number'] = zeros(
            [already_used_branches.shape[0], 1]).astype(int)
        BRANCHES = DataFrame(ppc_res['branch'][:, [0, 1, 8, 9]])
        for i in BRANCHES.index:
            from_bus = pp.get_element_index(pp_net,
                                            'bus',
                                            name=int(ppc_res['branch'][i, 0]))
            to_bus = pp.get_element_index(pp_net,
                                          'bus',
                                          name=int(ppc_res['branch'][i, 1]))
            from_vn_kv = ppc_res['bus'][from_bus, 9]
            to_vn_kv = ppc_res['bus'][to_bus, 9]
            ratio = BRANCHES[2].at[i]
            angle = BRANCHES[3].at[i]
            # from line results
            if (from_vn_kv == to_vn_kv) & ((ratio == 0) |
                                           (ratio == 1)) & (angle == 0):
                pp_res_branch = append(
                    pp_res_branch,
                    array(
                        pp_net.res_line[(pp_net.line.from_bus == from_bus)
                                        & (pp_net.line.to_bus == to_bus)]
                        [['p_from_kw', 'q_from_kvar', 'p_to_kw',
                          'q_to_kvar']])[int(already_used_branches.number.loc[
                              (already_used_branches.from_bus == from_bus)
                              & (already_used_branches.to_bus == to_bus)].
                                             values)].reshape(1, 4), 0)
                already_used_branches.number.loc[
                    (already_used_branches.from_bus == from_bus)
                    & (already_used_branches.to_bus == to_bus)] += 1
            # from trafo results
            else:
                if from_vn_kv >= to_vn_kv:
                    pp_res_branch = append(
                        pp_res_branch,
                        array(pp_net.res_trafo[
                            (pp_net.trafo.hv_bus == from_bus)
                            & (pp_net.trafo.lv_bus == to_bus)][[
                                'p_hv_kw', 'q_hv_kvar', 'p_lv_kw', 'q_lv_kvar'
                            ]])[int(already_used_branches.number.loc[
                                (already_used_branches.hv_bus == from_bus)
                                & (already_used_branches.lv_bus == to_bus)].
                                    values)].reshape(1, 4), 0)
                    already_used_branches.number.loc[
                        (already_used_branches.hv_bus == from_bus)
                        & (already_used_branches.lv_bus == to_bus)] += 1
                else:  # switch hv-lv-connection of pypower connection buses
                    pp_res_branch = append(
                        pp_res_branch,
                        array(pp_net.res_trafo[
                            (pp_net.trafo.hv_bus == to_bus)
                            & (pp_net.trafo.lv_bus == from_bus)][[
                                'p_lv_kw', 'q_lv_kvar', 'p_hv_kw', 'q_hv_kvar'
                            ]])[int(already_used_branches.number.loc[
                                (already_used_branches.hv_bus == to_bus)
                                & (already_used_branches.lv_bus == from_bus)].
                                    values)].reshape(1, 4), 0)
                    already_used_branches.number.loc[
                        (already_used_branches.hv_bus == to_bus)
                        & (already_used_branches.lv_bus == from_bus)] += 1
        pp_res_branch = pp_res_branch[1:, :]  # delete initial zero row

        # --- do the power flow result comparison
        diff_res_bus = ppc_res_bus - pp_res_bus
        diff_res_branch = ppc_res_branch - pp_res_branch * 1e-3
        diff_res_gen = ppc_res_gen + pp_res_gen * 1e-3
        # comparison of buses with several generator units only as q sum
        GEN_uniq = GENS.drop_duplicates()
        for i in GEN_uniq.loc[GEN_uniq[0].isin(change_q_compare)].index:
            next_is = GEN_uniq.index[GEN_uniq.index > i]
            if len(next_is) > 0:
                next_i = next_is[0]
            else:
                next_i = GENS.index[-1] + 1
            if (next_i - i) > 1:
                diff_res_gen[i:next_i, 1] = sum(diff_res_gen[i:next_i, 1])
        # logger info
        logger.debug(
            "Maximum voltage magnitude difference between pypower and pandapower: "
            "%.2e pu" % max(abs(diff_res_bus[:, 0])))
        logger.debug(
            "Maximum voltage angle difference between pypower and pandapower: "
            "%.2e degree" % max(abs(diff_res_bus[:, 1])))
        logger.debug(
            "Maximum branch flow active power difference between pypower and pandapower: "
            "%.2e kW" % max(abs(diff_res_branch[:, [0, 2]] * 1e3)))
        logger.debug(
            "Maximum branch flow reactive power difference between pypower and "
            "pandapower: %.2e kVAr" %
            max(abs(diff_res_branch[:, [1, 3]] * 1e3)))
        logger.debug(
            "Maximum active power generation difference between pypower and pandapower: "
            "%.2e kW" % max(abs(diff_res_gen[:, 0] * 1e3)))
        logger.debug(
            "Maximum reactive power generation difference between pypower and pandapower: "
            "%.2e kVAr" % max(abs(diff_res_gen[:, 1] * 1e3)))
        if (max(abs(diff_res_bus[:, 0])) < 1e-3) & (max(abs(diff_res_bus[:, 1])) < 1e-3) & \
                (max(abs(diff_res_branch[:, [0, 2]])) < 1e-3) & \
                (max(abs(diff_res_branch[:, [1, 3]])) < 1e-3) & \
                (max(abs(diff_res_gen)) > 1e-1).any():
            logger.debug(
                "The active/reactive power generation difference possibly results "
                "because of a pypower error. Please validate "
                "the results via pypower loadflow."
            )  # this occurs e.g. at ppc case9
        # give a return
        if type(max_diff_values) == dict:
            if Series([
                    'q_gen_kvar', 'p_branch_kw', 'q_branch_kvar', 'p_gen_kw',
                    'va_degree', 'vm_pu'
            ]).isin(Series(list(max_diff_values.keys()))).all():
                if (max(abs(diff_res_bus[:, 0])) < max_diff_values['vm_pu']) & \
                        (max(abs(diff_res_bus[:, 1])) < max_diff_values['va_degree']) & \
                        (max(abs(diff_res_branch[:, [0, 2]])) < max_diff_values['p_branch_kw'] /
                            1e3) & \
                        (max(abs(diff_res_branch[:, [1, 3]])) < max_diff_values['q_branch_kvar'] /
                            1e3) & \
                        (max(abs(diff_res_gen[:, 0])) < max_diff_values['p_gen_kw'] / 1e3) & \
                        (max(abs(diff_res_gen[:, 1])) < max_diff_values['q_gen_kvar'] / 1e3):
                    return True
                else:
                    return False
            else:
                logger.debug('Not all requried dict keys are provided.')
        else:
            logger.debug("'max_diff_values' must be a dict.")
Exemplo n.º 30
0
 def create_pp_load(self, element):
     bus = pp.get_element_index(
         self.net, "bus", element["connections"][0]['connectivityNodeId'])
     pp.create_load(self.net, bus=bus, p_mw=0)