|
1
|
|
|
import geopandas as gpd |
|
2
|
|
|
|
|
3
|
|
|
from egon.data import db |
|
4
|
|
|
from egon.data.datasets.power_plants.pv_rooftop_buildings import timer_func |
|
5
|
|
|
import egon.data.config |
|
6
|
|
|
|
|
7
|
|
View Code Duplication |
def assign_bus_id(power_plants, cfg): |
|
|
|
|
|
|
8
|
|
|
"""Assigns bus_ids to power plants according to location and voltage level |
|
9
|
|
|
|
|
10
|
|
|
Parameters |
|
11
|
|
|
---------- |
|
12
|
|
|
power_plants : pandas.DataFrame |
|
13
|
|
|
Power plants including voltage level |
|
14
|
|
|
|
|
15
|
|
|
Returns |
|
16
|
|
|
------- |
|
17
|
|
|
power_plants : pandas.DataFrame |
|
18
|
|
|
Power plants including voltage level and bus_id |
|
19
|
|
|
|
|
20
|
|
|
""" |
|
21
|
|
|
|
|
22
|
|
|
mv_grid_districts = db.select_geodataframe( |
|
23
|
|
|
f""" |
|
24
|
|
|
SELECT * FROM {cfg['sources']['egon_mv_grid_district']} |
|
25
|
|
|
""", |
|
26
|
|
|
epsg=4326, |
|
27
|
|
|
) |
|
28
|
|
|
|
|
29
|
|
|
ehv_grid_districts = db.select_geodataframe( |
|
30
|
|
|
f""" |
|
31
|
|
|
SELECT * FROM {cfg['sources']['ehv_voronoi']} |
|
32
|
|
|
""", |
|
33
|
|
|
epsg=4326, |
|
34
|
|
|
) |
|
35
|
|
|
|
|
36
|
|
|
# Assign power plants in hv and below to hvmv bus |
|
37
|
|
|
power_plants_hv = power_plants[power_plants.voltage_level >= 3].index |
|
38
|
|
|
if len(power_plants_hv) > 0: |
|
39
|
|
|
power_plants.loc[power_plants_hv, "bus_id"] = gpd.sjoin( |
|
40
|
|
|
power_plants[power_plants.index.isin(power_plants_hv)], |
|
41
|
|
|
mv_grid_districts, |
|
42
|
|
|
).bus_id |
|
43
|
|
|
|
|
44
|
|
|
# Assign power plants in ehv to ehv bus |
|
45
|
|
|
power_plants_ehv = power_plants[power_plants.voltage_level < 3].index |
|
46
|
|
|
|
|
47
|
|
|
if len(power_plants_ehv) > 0: |
|
48
|
|
|
ehv_join = gpd.sjoin( |
|
49
|
|
|
power_plants[power_plants.index.isin(power_plants_ehv)], |
|
50
|
|
|
ehv_grid_districts, |
|
51
|
|
|
) |
|
52
|
|
|
|
|
53
|
|
|
if "bus_id_right" in ehv_join.columns: |
|
54
|
|
|
power_plants.loc[power_plants_ehv, "bus_id"] = gpd.sjoin( |
|
55
|
|
|
power_plants[power_plants.index.isin(power_plants_ehv)], |
|
56
|
|
|
ehv_grid_districts, |
|
57
|
|
|
).bus_id_right |
|
58
|
|
|
|
|
59
|
|
|
else: |
|
60
|
|
|
power_plants.loc[power_plants_ehv, "bus_id"] = gpd.sjoin( |
|
61
|
|
|
power_plants[power_plants.index.isin(power_plants_ehv)], |
|
62
|
|
|
ehv_grid_districts, |
|
63
|
|
|
).bus_id |
|
64
|
|
|
|
|
65
|
|
|
# Assert that all power plants have a bus_id |
|
66
|
|
|
assert power_plants.bus_id.notnull().all(), f"""Some power plants are |
|
67
|
|
|
not attached to a bus: {power_plants[power_plants.bus_id.isnull()]}""" |
|
68
|
|
|
|
|
69
|
|
|
return power_plants |
|
70
|
|
|
|
|
71
|
|
|
|
|
72
|
|
|
@timer_func |
|
73
|
|
|
def add_missing_bus_ids(scn_name): |
|
74
|
|
|
"""Assign busses by spatal intersection of mvgrid districts or ehv voronois.""" |
|
75
|
|
|
|
|
76
|
|
|
sql = f""" |
|
77
|
|
|
-- Assign missing buses to mv grid district buses for HV and below |
|
78
|
|
|
UPDATE supply.egon_power_plants AS epp |
|
79
|
|
|
SET bus_id = ( |
|
80
|
|
|
SELECT emgd.bus_id |
|
81
|
|
|
FROM grid.egon_mv_grid_district AS emgd |
|
82
|
|
|
WHERE ST_Intersects(ST_Transform(epp.geom, 4326), ST_Transform(emgd.geom, 4326)) |
|
83
|
|
|
ORDER BY ST_Transform(emgd.geom, 4326) <-> ST_Transform(epp.geom, 4326) |
|
84
|
|
|
LIMIT 1 |
|
85
|
|
|
) |
|
86
|
|
|
WHERE (epp.carrier = 'solar' |
|
87
|
|
|
OR epp.carrier = 'wind_onshore' |
|
88
|
|
|
OR epp.carrier = 'solar_rooftop' |
|
89
|
|
|
OR epp.carrier = 'wind_offshore') |
|
90
|
|
|
AND epp.scenario = '{scn_name}' |
|
91
|
|
|
AND epp.bus_id is null |
|
92
|
|
|
AND epp.voltage_level >= 3; -- HV and below |
|
93
|
|
|
|
|
94
|
|
|
|
|
95
|
|
|
-- Assign missing buses to EHV buses for EHV |
|
96
|
|
|
UPDATE supply.egon_power_plants AS epp |
|
97
|
|
|
SET bus_id = ( |
|
98
|
|
|
SELECT eesv.bus_id |
|
99
|
|
|
FROM grid.egon_ehv_substation_voronoi AS eesv |
|
100
|
|
|
WHERE ST_Intersects(ST_Transform(epp.geom, 4326), ST_Transform(eesv.geom, 4326)) |
|
101
|
|
|
ORDER BY ST_Transform(eesv.geom, 4326) <-> ST_Transform(epp.geom, 4326) |
|
102
|
|
|
LIMIT 1 |
|
103
|
|
|
) |
|
104
|
|
|
WHERE (epp.carrier = 'solar' |
|
105
|
|
|
OR epp.carrier = 'wind_onshore' |
|
106
|
|
|
OR epp.carrier = 'solar_rooftop' |
|
107
|
|
|
OR epp.carrier = 'wind_offshore') |
|
108
|
|
|
AND epp.scenario = '{scn_name}' |
|
109
|
|
|
AND epp.bus_id is null |
|
110
|
|
|
AND epp.voltage_level < 3; --EHV |
|
111
|
|
|
|
|
112
|
|
|
|
|
113
|
|
|
""" |
|
114
|
|
|
|
|
115
|
|
|
db.execute_sql(sql) |
|
116
|
|
|
|
|
117
|
|
|
|
|
118
|
|
|
@timer_func |
|
119
|
|
|
def find_weather_id(scn_name): |
|
120
|
|
|
|
|
121
|
|
|
sql = f"""UPDATE supply.egon_power_plants AS epp |
|
122
|
|
|
SET weather_cell_id = ( |
|
123
|
|
|
SELECT eewc.w_id |
|
124
|
|
|
FROM supply.egon_era5_weather_cells AS eewc |
|
125
|
|
|
WHERE ST_Intersects(epp.geom, eewc.geom) |
|
126
|
|
|
ORDER BY eewc.geom <-> epp.geom |
|
127
|
|
|
LIMIT 1 |
|
128
|
|
|
) |
|
129
|
|
|
WHERE (epp.carrier = 'solar' |
|
130
|
|
|
OR epp.carrier = 'solar_rooftop' |
|
131
|
|
|
OR epp.carrier = 'wind_onshore' |
|
132
|
|
|
OR epp.carrier = 'wind_offshore') |
|
133
|
|
|
AND epp.scenario = '{scn_name}'; |
|
134
|
|
|
""" |
|
135
|
|
|
|
|
136
|
|
|
db.execute_sql(sql) |
|
137
|
|
|
|
|
138
|
|
|
|
|
139
|
|
|
def weatherId_and_busId(): |
|
140
|
|
|
for scn_name in egon.data.config.settings()["egon-data"]["--scenarios"]: |
|
141
|
|
|
find_weather_id(scn_name) |
|
142
|
|
|
add_missing_bus_ids(scn_name) |
|
143
|
|
|
|