def test_mv_oberrhein(): scenarios = ["load", "generation"] include_substations = [False, True] separation_by_sub = [False, True] for i in scenarios: for j in include_substations: for k in separation_by_sub: net = pn.mv_oberrhein(scenario=i, include_substations=j) pp.runpp(net) if i == "load": assert net.sgen.scaling.mean() < 0.2 assert net.load.scaling.mean() > 0.5 elif i == "generation": net.sgen.scaling.mean() > 0.6 net.load.scaling.mean() < 0.2 if j is False: assert len(net.bus) == 179 assert len(net.trafo) == 2 elif j is True: assert len(net.bus) == 320 assert len(net.trafo) == 143 assert len(net.line) == 181 assert len(net.switch) == 322 assert net.converged if k is True: net0, net1 = pn.mv_oberrhein(scenario=i, include_substations=j, separation_by_sub=k) assert len(net1.keys()) == len(net0.keys()) == len(net.keys()) assert net1.res_ext_grid.loc[1].all() == net.res_ext_grid.loc[1].all() assert net0.res_ext_grid.loc[0].all() == net.res_ext_grid.loc[0].all() assert len(net.bus) == len(net0.bus) + len(net1.bus)
def test_new_pp_object_io(): net = networks.mv_oberrhein() ds = DFData(pd.DataFrame(data=np.array([[0, 1, 2], [7, 8, 9]]))) control.ConstControl(net, 'sgen', 'p_mw', 42, profile_name=0, data_source=ds) control.ContinuousTapControl(net, 142, 1) obj = net.controller.object.at[0] obj.run = pp.runpp s = json.dumps(net, cls=PPJSONEncoder) net1 = json.loads(s, cls=PPJSONDecoder) obj1 = net1.controller.object.at[0] obj2 = net1.controller.object.at[1] assert isinstance(obj1, control.ConstControl) assert isinstance(obj2, control.ContinuousTapControl) assert obj1.run is pp.runpp assert isinstance(obj1.data_source, DFData) assert isinstance(obj1.data_source.df, pd.DataFrame)
def test_mv_oberrhein(): scenarios = ["load", "generation"] include_substations = [False, True] for i in scenarios: for j in include_substations: net = pn.mv_oberrhein(scenario=i, include_substations=j) pp.runpp(net) if i == "load": assert net.sgen.scaling.mean() < 0.2 assert net.load.scaling.mean() > 0.5 elif i == "generation": net.sgen.scaling.mean() > 0.6 net.load.scaling.mean() < 0.2 if j is False: assert len(net.bus) == 179 assert len(net.trafo) == 2 elif j is True: assert len(net.bus) == 320 assert len(net.trafo) == 143 assert len(net.line) == 181 assert len(net.switch) == 322 assert net.converged
def test_deepcopy_controller(): net = nw.mv_oberrhein() ct.ContinuousTapControl(net, 114, 1.01) assert net == net.controller.object.iloc[0].net net2 = copy.deepcopy(net) assert net2 == net2.controller.object.iloc[0].net net3 = copy.copy(net) assert net3 == net3.controller.object.iloc[0].net
def test_json_different_nets(): net = networks.mv_oberrhein() net2 = networks.simple_four_bus_system() control.ContinuousTapControl(net, 114, 1.02) net.tuple = (1, "4") net.mg = topology.create_nxgraph(net) json_string = json.dumps([net, net2], cls=PPJSONEncoder) [net_out, net2_out] = json.loads(json_string, cls=PPJSONDecoder) assert_net_equal(net_out, net) assert_net_equal(net2_out, net2) pp.runpp(net_out, run_control=True) pp.runpp(net, run_control=True) assert_net_equal(net, net_out)
def test_merge_and_split_nets(): net1 = nw.mv_oberrhein() # TODO there are some geodata values in oberrhein without corresponding lines net1.line_geodata.drop(set(net1.line_geodata.index) - set(net1.line.index), inplace=True) n1 = len(net1.bus) pp.runpp(net1) net2 = nw.create_cigre_network_mv() pp.runpp(net2) net = pp.merge_nets(net1, net2) pp.runpp(net) assert np.allclose(net.res_bus.vm_pu.iloc[:n1].values, net1.res_bus.vm_pu.values) assert np.allclose(net.res_bus.vm_pu.iloc[n1:].values, net2.res_bus.vm_pu.values) net3 = pp.select_subnet(net, net.bus.index[:n1], include_results=True) assert pp.dataframes_equal(net3.res_bus[["vm_pu"]], net1.res_bus[["vm_pu"]]) net4 = pp.select_subnet(net, net.bus.index[n1:], include_results=True) assert np.allclose(net4.res_bus.vm_pu.values, net2.res_bus.vm_pu.values)
def test_opf_oberrhein(): """ Testing a simple network with transformer for loading constraints with OPF using a generator """ # create net net = nw.mv_oberrhein() net.bus["max_vm_pu"] = 1.1 net.bus["min_vm_pu"] = 0.9 net.line["max_loading_percent"] = 200 net.trafo["max_loading_percent"] = 100 net.sgen["min_p_mw"] = -net.sgen.sn_mva net.sgen["max_p_mw"] = 0 net.sgen["max_q_mvar"] = 1 net.sgen["min_q_mvar"] = -1 net.sgen["controllable"] = True net.load["controllable"] = False # run OPF pp.runopp(net, calculate_voltage_angles=False) assert net["OPF_converged"]
def test_json_encoding_decoding(): net = nw.mv_oberrhein() net.tuple = (1, "4") s = set(['1', 4]) t = tuple(['2', 3]) f = frozenset(['12', 3]) a = np.array([1., 2.]) d = {"a": net, "b": f} json_string = json.dumps([s, t, f, net, a, d], cls=PPJSONEncoder) s1, t1, f1, net1, a1, d1 = json.loads(json_string, cls=PPJSONDecoder) assert s == s1 assert t == t1 assert f == f1 assert net.tuple == net1.tuple assert np.allclose(a, a1) #TODO line_geodata isn't the same since tuples inside DataFrames are converted to lists (see test_json_tuple_in_dataframe) assert pp.nets_equal(net, net1, exclude_elms=["line_geodata"]) assert pp.nets_equal(d["a"], d1["a"], exclude_elms=["line_geodata"]) assert d["b"] == d1["b"]
{ "x": dist.loc[net.bus.index.values].values, "y": voltages.loc[net.bus.index.values].values }, index=net.bus.index) return bgd if __name__ == "__main__": import pandapower as pp import pandapower.networks as nw import pandas as pd import networkx as nx import plotting net = nw.mv_oberrhein() pp.runpp(net) mg = top.create_nxgraph(net, respect_switches=True) feeders = list( top.connected_components(mg, notravbuses=set(net.trafo.lv_bus.values))) lines_with_open_switches = set( net.switch.query("not closed and et == 'l'").element.values) fig, axs = plt.subplots(2) for bgd, ax in zip( [net.bus_geodata, voltage_profile_to_bus_geodata(net)], axs): for color, f in zip(["C0", "C1", "C2", "C3"], feeders): l = set(net.line.index[net.line.from_bus.isin( f)]) - lines_with_open_switches c = plotting.create_line_collection(net, lines=l,
line_trace_vlev = create_line_trace(net, lines=vlev_lines, use_line_geodata=use_line_geodata, respect_switches=respect_switches, legendgroup=str(vn_kv), color=vlev_color, width=line_width, trace_name='lines {0} kV'.format(vn_kv)) if line_trace_vlev is not None: line_traces += line_trace_vlev trafo_traces = create_trafo_trace(net, color='gray', width=line_width * 2) draw_traces(line_traces + trafo_traces + bus_traces, showlegend=True, aspectratio=aspectratio, on_map=on_map, map_style=map_style, figsize=figsize) if __name__ == '__main__': from pandapower.plotting.plotly import simple_plotly from pandapower.networks import mv_oberrhein from pandapower import runpp net = mv_oberrhein() vlevel_plotly(net) runpp(net) line_width=2 bus_size=10 use_line_geodata = None graph = create_nxgraph(net, include_trafos=False) vlev_buses = connected_components(graph) respect_switches = True # getting unique sets of buses for each voltage level vlev_bus_dict = {} for vl_buses in vlev_buses: if net.bus.loc[vl_buses, 'vn_kv'].unique().shape[0] > 1: logger.warning('buses from the same voltage level does not have the same vn_kv !?') vn_kv = net.bus.loc[vl_buses, 'vn_kv'].unique()[0]
def simple_plot(net=None, respect_switches=False, line_width=1.0, bus_size=1.0, ext_grid_size=1.0, bus_color=colors[0], line_color='grey', trafo_color='g', ext_grid_color='y'): """ Plots a pandapower network as simple as possible. If no geodata is available, artificial geodata is generated. For advanced plotting see the tutorial INPUT: **net** - The pandapower format network. If none is provided, mv_oberrhein() will be plotted as an example OPTIONAL: **respect_switches** (bool, False) - Respect switches when artificial geodata is created **line_width** (float, 1.0) - width of lines **bus_size** (float, 1.0) - Relative size of buses to plot. The value bus_size is multiplied with mean_distance_between_buses, which equals the distance between the max geoocord and the min divided by 200. mean_distance_between_buses = sum((net['bus_geodata'].max() - net['bus_geodata'].min()) / 200) **ext_grid_size** (float, 1.0) - Relative size of ext_grids to plot. See bus sizes for details. Note: ext_grids are plottet as rectangles **bus_color** (String, colors[0]) - Bus Color. Init as first value of color palette. Usually colors[0] = "b". **line_color** (String, 'grey') - Line Color. Init is grey **trafo_color** (String, 'g') - Trafo Color. Init is green **ext_grid_color** (String, 'y') - External Grid Color. Init is yellow """ if net is None: import pandapower.networks as nw logger.warning( "No pandapower network provided -> Plotting mv_oberrhein") net = nw.mv_oberrhein() # create geocoord if none are available if len(net.line_geodata) == 0 and len(net.bus_geodata) == 0: logger.warning( "No or insufficient geodata available --> Creating artificial coordinates." + " This may take some time") create_generic_coordinates(net, respect_switches=respect_switches) if bus_size or ext_grid_size is None: # if either bus_size or ext_grid size is None -> calc size from distance between min and # max geocoord mean_distance_between_buses = sum( (net['bus_geodata'].max() - net['bus_geodata'].min()) / 200) # set the bus / ext_grid sizes accordingly # Comment: This is implemented because if you would choose a fixed values # (e.g. bus_size = 0.2), the size # could be to small for large networks and vice versa bus_size *= mean_distance_between_buses ext_grid_size *= mean_distance_between_buses * 1.5 # if bus geodata is available, but no line geodata use_line_geodata = False if len(net.line_geodata) == 0 else True # create bus collections ti plot bc = create_bus_collection(net, net.bus.index, size=bus_size, color=bus_color, zorder=10) lc = create_line_collection(net, net.line.index, color=line_color, linewidths=line_width, use_line_geodata=use_line_geodata) collections = [bc, lc] eg_buses_with_geocoordinates = set(net.ext_grid.bus.values) & set( net.bus_geodata.index) if len(eg_buses_with_geocoordinates) > 0: sc = create_bus_collection(net, eg_buses_with_geocoordinates, patch_type="rect", size=ext_grid_size, color=ext_grid_color, zorder=11) collections.append(sc) # create trafo collection if trafo is available trafo_buses_with_geocoordinates = [t for t, trafo in net.trafo.iterrows() \ if trafo.hv_bus in net.bus_geodata.index \ and trafo.lv_bus in net.bus_geodata.index] if len(trafo_buses_with_geocoordinates) > 0: tc = create_trafo_collection(net, trafo_buses_with_geocoordinates, color=trafo_color) collections.append(tc) draw_collections(collections) plt.show()
import pandapower.networks as nw1 import pandapower as pp from pandapower.plotting import simple_plot, simple_plotly, pf_res_plotly net1 = nw1.mv_oberrhein() pp.runpp(net1) print(net1.res_bus) highest = net1.res_bus.vm_pu.max() print(highest) highest_ones = net1.res_bus.loc[net1.res_bus.vm_pu > 1.02] print(highest_ones) lines = net1.res_line.loc[net1.res_line.loading_percent > 50.] print(lines) simple_plot(net1) simple_plotly(net1) print()
""" Created on Wed Dec 16 17:15:39 2020 @author: rouna """ import numpy as np import pandas as pd import pandapower.control as control import pandapower.networks as nw import pandapower.timeseries as timeseries from pandapower.timeseries.data_sources.frame_data import DFData # load a pandapower network net = nw.mv_oberrhein(scenario='generation') # number of time steps n_ts = 95 # load your timeseries from a file (here csv file) # df = pd.read_csv("sgen_timeseries.csv") # or create a DataFrame with some random time series as an example df = pd.DataFrame(np.random.normal(1., 0.1, size=(n_ts, len(net.sgen.index))), index=list(range(n_ts)), columns=net.sgen.index) * net.sgen.p_mw.values # create the data source from it ds = DFData(df) # initialising ConstControl controller to update values of the regenerative generators ("sgen" elements) # the element_index specifies which elements to update (here all sgens in the net since net.sgen.index is passed) # the controlled variable is "p_mw" # the profile_name are the columns in the csv file (here this is also equal to the sgen indices 0-N ) const_sgen = control.ConstControl(net, element='sgen', element_index=net.sgen.index,