Spaces:
Sleeping
Sleeping
Upload 2 files
Browse filestranslation into german, price duration curve and ror upper limmit
- Input_Jahr_2021.xlsx +2 -2
- app.py +34 -35
Input_Jahr_2021.xlsx
CHANGED
@@ -1,3 +1,3 @@
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:
|
3 |
-
size
|
|
|
1 |
version https://git-lfs.github.com/spec/v1
|
2 |
+
oid sha256:6e554203fe49d3bb990ec181e26aee4d05950ee07dadc980bdbade651962c6ed
|
3 |
+
size 1119734
|
app.py
CHANGED
@@ -52,7 +52,7 @@ with col1:
|
|
52 |
st.download_button('Download Excel Vorlage', f, file_name='Input_Jahr_2021.xlsx') # Defaults to 'application/octet-stream'
|
53 |
|
54 |
#url_excel = r'Input_Jahr_2021.xlsx'
|
55 |
-
url_excel = st.file_uploader(label = 'Excel
|
56 |
|
57 |
|
58 |
if url_excel == None:
|
@@ -114,24 +114,24 @@ e2p_iSto = params_dict['e2p_iSto']
|
|
114 |
# Sliders and input boxes for parameters
|
115 |
with col2:
|
116 |
# Slider for CO2 limit [mio. t]
|
117 |
-
l_co2 = st.slider(value=int(params_dict['l_co2']), min_value=0, max_value=750, label="CO2
|
118 |
|
119 |
# Slider for H2 price / usevalue [€/MWH_th]
|
120 |
price_h2 = st.slider(value=100, min_value=0, max_value=300, label="Wasserstoffpreis [€/MWh]", step=10)
|
121 |
|
122 |
for i_idx in c_fuel_i.get_index('i'):
|
123 |
if i_idx in ['Braunkohle']:
|
124 |
-
c_fuel_i.loc[i_idx] = st.slider(value=int(c_fuel_i.loc[i_idx]), min_value=0, max_value=300, label=i_idx + '
|
125 |
|
126 |
-
dt = st.number_input(label="
|
127 |
|
128 |
with col3:
|
129 |
# Slider for CO2 limit [mio. t]
|
130 |
for i_idx in c_fuel_i.get_index('i'):
|
131 |
if i_idx in ['Steinkohle', 'Erdöl','Erdgas']:
|
132 |
-
c_fuel_i.loc[i_idx] = st.slider(value=int(c_fuel_i.loc[i_idx]), min_value=0, max_value=300, label=i_idx + '
|
133 |
|
134 |
-
technologies_invest = st.multiselect(label='
|
135 |
technologies_no_invest = [x for x in i if x not in technologies_invest]
|
136 |
|
137 |
# Aggregate time series
|
@@ -220,7 +220,7 @@ filling_iSto_t = m.add_constraints(l.sel(i = iSto) - (l.sel(i = iSto).roll(t = -
|
|
220 |
CO2_limit = m.add_constraints(((y / eff_i) * co2_factor_i * dt).sum() <= l_co2 * 1_000_000 , name = 'CO2_limit')
|
221 |
|
222 |
## set run-of-river power plants capacity limit to 5 GW
|
223 |
-
|
224 |
|
225 |
|
226 |
# %%
|
@@ -237,7 +237,7 @@ colb1, colb2 = st.columns(2)
|
|
237 |
# Assuming df_excel has columns 'All' and 'Capacities'
|
238 |
|
239 |
fig = px.bar((m.solution['K']+K_0_i).to_dataframe(name='K').reset_index(), \
|
240 |
-
y='i', x='K', orientation='h', title='
|
241 |
|
242 |
#fig
|
243 |
|
@@ -247,7 +247,7 @@ total_costs_rounded = round(total_costs/1e9, 2)
|
|
247 |
df_total_costs = pd.DataFrame({'Total costs':[total_costs]})
|
248 |
|
249 |
with colb1:
|
250 |
-
st.write('
|
251 |
|
252 |
# %%
|
253 |
#df_Co2_price = pd.DataFrame({'CO2_Price: ':[float(m.constraints['CO2_limit'].dual.values) * (-1)]})
|
@@ -257,11 +257,11 @@ df_CO2_price = pd.DataFrame({'CO2 price':[CO2_price]})
|
|
257 |
|
258 |
with colb2:
|
259 |
#st.write(str(df_Co2_price))
|
260 |
-
st.write('CO2
|
261 |
|
262 |
# %%
|
263 |
df_new_capacities = m.solution['K'].to_dataframe().reset_index()
|
264 |
-
fig = px.bar(m.solution['K'].to_dataframe().reset_index(), y='i', x='K', orientation='h', title='
|
265 |
|
266 |
with colb1:
|
267 |
fig
|
@@ -277,7 +277,7 @@ total_k_sum = df_new_capacities_rounded["K"].sum()
|
|
277 |
|
278 |
#df_new_capacities_rounded["percentage"] = df_new_capacities_rounded["K"].apply(lambda x: (x/total_k_sum)*100).abs().round(2)
|
279 |
|
280 |
-
fig = px.pie(df_new_capacities_rounded, names='i', values='K', title='
|
281 |
color='i', color_discrete_map=color_dict)
|
282 |
|
283 |
with colb1:
|
@@ -289,7 +289,7 @@ with colb1:
|
|
289 |
# %%
|
290 |
i_with_capacity = m.solution['K'].where( m.solution['K'] > 0).dropna(dim = 'i').get_index('i')
|
291 |
df_production = m.solution['y'].sel(i = i_with_capacity).to_dataframe().reset_index()
|
292 |
-
fig = px.area(m.solution['y'].sel(i = i_with_capacity).to_dataframe().reset_index(), y='y', x='t', title='
|
293 |
fig.update_traces(line=dict(width=0))
|
294 |
fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
|
295 |
|
@@ -299,7 +299,7 @@ with colb2:
|
|
299 |
#Add pie chart of total production per technology type in GWh(divide by 1000)
|
300 |
df_production_sum = (df_production.groupby('i')['y'].sum() * dt / 1000 ).round(0).sort_values(ascending=False).reset_index()
|
301 |
|
302 |
-
fig = px.pie(df_production_sum, names="i", values='y', title='
|
303 |
color='i', color_discrete_map=color_dict)
|
304 |
|
305 |
with colb2:
|
@@ -308,18 +308,17 @@ with colb2:
|
|
308 |
# %%
|
309 |
|
310 |
df_price = m.constraints['load'].dual.to_dataframe().reset_index()
|
311 |
-
#df_price['dual'] = df_price['dual']
|
312 |
|
313 |
-
|
314 |
-
fig = px.line(df_price, y='dual', x='t', title='Electricity prices [€/MWh]', range_y=[0,250])
|
315 |
with colb1:
|
316 |
fig
|
317 |
|
318 |
|
319 |
# %%
|
320 |
-
df_sorted_price = df_price["dual"].repeat(dt).sort_values(ascending=False).reset_index(drop=True)/int(dt)
|
|
|
321 |
|
322 |
-
fig = px.line(y=df_sorted_price, x=df_sorted_price.index, title='
|
323 |
with colb1:
|
324 |
fig
|
325 |
|
@@ -331,7 +330,7 @@ df_contr_marg['dual'] = df_contr_marg['dual'] / dt * (-1)
|
|
331 |
|
332 |
# %%
|
333 |
|
334 |
-
fig = px.line(df_contr_marg, y='dual', x='t',title='
|
335 |
with colb2:
|
336 |
fig
|
337 |
|
@@ -339,7 +338,7 @@ with colb2:
|
|
339 |
|
340 |
# curtailment
|
341 |
df_curtailment = m.solution['y_curt'].sel(i = iRes).to_dataframe().reset_index()
|
342 |
-
fig = px.area(m.solution['y_curt'].sel(i = iRes).to_dataframe().reset_index(), y='y_curt', x='t', title='
|
343 |
fig.update_traces(line=dict(width=0))
|
344 |
fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
|
345 |
|
@@ -348,7 +347,7 @@ with colb1:
|
|
348 |
|
349 |
# %%
|
350 |
df_charging = m.solution['y_ch'].sel(i = iSto).to_dataframe().reset_index()
|
351 |
-
fig = px.area(m.solution['y_ch'].sel(i = iSto).to_dataframe().reset_index(), y='y_ch', x='t', title='
|
352 |
fig.update_traces(line=dict(width=0))
|
353 |
fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
|
354 |
|
@@ -357,7 +356,7 @@ with colb2:
|
|
357 |
|
358 |
# %%
|
359 |
df_h2_prod = m.solution['y_h2'].sel(i = iPtG).to_dataframe().reset_index()
|
360 |
-
fig = px.area(m.solution['y_h2'].sel(i = iPtG).to_dataframe().reset_index(), y='y_h2', x='t', title='
|
361 |
fig.update_traces(line=dict(width=0))
|
362 |
fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
|
363 |
|
@@ -403,22 +402,22 @@ def disaggregate_df(df):
|
|
403 |
# Create a Pandas Excel writer using XlsxWriter as the engine
|
404 |
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
|
405 |
# Write each DataFrame to a different sheet
|
406 |
-
disaggregate_df(df_total_costs).to_excel(writer, sheet_name='
|
407 |
-
disaggregate_df(df_CO2_price).to_excel(writer, sheet_name='CO2
|
408 |
-
disaggregate_df(df_price).to_excel(writer, sheet_name='
|
409 |
-
disaggregate_df(df_contr_marg).to_excel(writer, sheet_name='
|
410 |
-
disaggregate_df(df_new_capacities).to_excel(writer, sheet_name='
|
411 |
-
disaggregate_df(df_production).to_excel(writer, sheet_name='
|
412 |
-
disaggregate_df(df_charging).to_excel(writer, sheet_name='
|
413 |
-
disaggregate_df(D_t.to_dataframe().reset_index()).to_excel(writer, sheet_name='
|
414 |
-
disaggregate_df(df_curtailment).to_excel(writer, sheet_name='
|
415 |
-
disaggregate_df(df_h2_prod).to_excel(writer, sheet_name='H2
|
416 |
|
417 |
with col4:
|
418 |
st.download_button(
|
419 |
-
label="Download Excel
|
420 |
data=output.getvalue(),
|
421 |
-
file_name="
|
422 |
mime="application/vnd.ms-excel"
|
423 |
)
|
424 |
|
|
|
52 |
st.download_button('Download Excel Vorlage', f, file_name='Input_Jahr_2021.xlsx') # Defaults to 'application/octet-stream'
|
53 |
|
54 |
#url_excel = r'Input_Jahr_2021.xlsx'
|
55 |
+
url_excel = st.file_uploader(label = 'Excel Datei hochladen')
|
56 |
|
57 |
|
58 |
if url_excel == None:
|
|
|
114 |
# Sliders and input boxes for parameters
|
115 |
with col2:
|
116 |
# Slider for CO2 limit [mio. t]
|
117 |
+
l_co2 = st.slider(value=int(params_dict['l_co2']), min_value=0, max_value=750, label="CO2 Limit [Mio. t]", step=10)
|
118 |
|
119 |
# Slider for H2 price / usevalue [€/MWH_th]
|
120 |
price_h2 = st.slider(value=100, min_value=0, max_value=300, label="Wasserstoffpreis [€/MWh]", step=10)
|
121 |
|
122 |
for i_idx in c_fuel_i.get_index('i'):
|
123 |
if i_idx in ['Braunkohle']:
|
124 |
+
c_fuel_i.loc[i_idx] = st.slider(value=int(c_fuel_i.loc[i_idx]), min_value=0, max_value=300, label=i_idx + ' Preis [€/MWh]' , step=10)
|
125 |
|
126 |
+
dt = st.number_input(label="Zeitliche Auflösung [h]", min_value=1, max_value=len(t), value=6, help="Geben Sie nur ganze Zahlen zwischen 1 und 8760 (oder 8784 für Schaltjahre) ein.")
|
127 |
|
128 |
with col3:
|
129 |
# Slider for CO2 limit [mio. t]
|
130 |
for i_idx in c_fuel_i.get_index('i'):
|
131 |
if i_idx in ['Steinkohle', 'Erdöl','Erdgas']:
|
132 |
+
c_fuel_i.loc[i_idx] = st.slider(value=int(c_fuel_i.loc[i_idx]), min_value=0, max_value=300, label=i_idx + ' Preis [€/MWh]' , step=10)
|
133 |
|
134 |
+
technologies_invest = st.multiselect(label='Technologien für Investitionen', options=i, default=['Braunkohle','Erdgas','Steinkohle','Erdöl','PV','WindOff','WindOn','H2','Laufwasser','Batteriespeicher', 'Elektrolyseur'])
|
135 |
technologies_no_invest = [x for x in i if x not in technologies_invest]
|
136 |
|
137 |
# Aggregate time series
|
|
|
220 |
CO2_limit = m.add_constraints(((y / eff_i) * co2_factor_i * dt).sum() <= l_co2 * 1_000_000 , name = 'CO2_limit')
|
221 |
|
222 |
## set run-of-river power plants capacity limit to 5 GW
|
223 |
+
RoR_cap = m.add_constraints(K.sel(i = 'Laufwasser') <= 5000, name = 'RoR_cap')
|
224 |
|
225 |
|
226 |
# %%
|
|
|
237 |
# Assuming df_excel has columns 'All' and 'Capacities'
|
238 |
|
239 |
fig = px.bar((m.solution['K']+K_0_i).to_dataframe(name='K').reset_index(), \
|
240 |
+
y='i', x='K', orientation='h', title='Installierte Kapazitäten insgesamt [MW]', color='i')
|
241 |
|
242 |
#fig
|
243 |
|
|
|
247 |
df_total_costs = pd.DataFrame({'Total costs':[total_costs]})
|
248 |
|
249 |
with colb1:
|
250 |
+
st.write('Gesamtkosten: ' + str(total_costs_rounded) + ' Mrd. €')
|
251 |
|
252 |
# %%
|
253 |
#df_Co2_price = pd.DataFrame({'CO2_Price: ':[float(m.constraints['CO2_limit'].dual.values) * (-1)]})
|
|
|
257 |
|
258 |
with colb2:
|
259 |
#st.write(str(df_Co2_price))
|
260 |
+
st.write('CO2 Preis: ' + str(CO2_price_rounded) + ' €/t')
|
261 |
|
262 |
# %%
|
263 |
df_new_capacities = m.solution['K'].to_dataframe().reset_index()
|
264 |
+
fig = px.bar(m.solution['K'].to_dataframe().reset_index(), y='i', x='K', orientation='h', title='Neu installierte Kapazitäten [MW]', color='i', color_discrete_map=color_dict)
|
265 |
|
266 |
with colb1:
|
267 |
fig
|
|
|
277 |
|
278 |
#df_new_capacities_rounded["percentage"] = df_new_capacities_rounded["K"].apply(lambda x: (x/total_k_sum)*100).abs().round(2)
|
279 |
|
280 |
+
fig = px.pie(df_new_capacities_rounded, names='i', values='K', title='Neu installierte Kapazitäten [MW] als Kuchendiagramm',
|
281 |
color='i', color_discrete_map=color_dict)
|
282 |
|
283 |
with colb1:
|
|
|
289 |
# %%
|
290 |
i_with_capacity = m.solution['K'].where( m.solution['K'] > 0).dropna(dim = 'i').get_index('i')
|
291 |
df_production = m.solution['y'].sel(i = i_with_capacity).to_dataframe().reset_index()
|
292 |
+
fig = px.area(m.solution['y'].sel(i = i_with_capacity).to_dataframe().reset_index(), y='y', x='t', title='Stromproduktion Lastgang [MW]', color='i', color_discrete_map=color_dict)
|
293 |
fig.update_traces(line=dict(width=0))
|
294 |
fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
|
295 |
|
|
|
299 |
#Add pie chart of total production per technology type in GWh(divide by 1000)
|
300 |
df_production_sum = (df_production.groupby('i')['y'].sum() * dt / 1000 ).round(0).sort_values(ascending=False).reset_index()
|
301 |
|
302 |
+
fig = px.pie(df_production_sum, names="i", values='y', title='Gesamtproduktion [GWh] als Kuchendiagramm',
|
303 |
color='i', color_discrete_map=color_dict)
|
304 |
|
305 |
with colb2:
|
|
|
308 |
# %%
|
309 |
|
310 |
df_price = m.constraints['load'].dual.to_dataframe().reset_index()
|
|
|
311 |
|
312 |
+
fig = px.line(df_price, y='dual', x='t', title='Strompreis [€/MWh]', range_y=[0,350])
|
|
|
313 |
with colb1:
|
314 |
fig
|
315 |
|
316 |
|
317 |
# %%
|
318 |
+
# df_sorted_price = df_price["dual"].repeat(dt).sort_values(ascending=False).reset_index(drop=True)/int(dt)
|
319 |
+
df_sorted_price = df_price["dual"].sort_values(ascending=False).reset_index(drop=True)
|
320 |
|
321 |
+
fig = px.line(y=df_sorted_price, x=df_sorted_price.index, title='Preisdauerlinie [€/MWh]', labels={"x": "Stunden im Jahr"},range_y=[0,350])
|
322 |
with colb1:
|
323 |
fig
|
324 |
|
|
|
330 |
|
331 |
# %%
|
332 |
|
333 |
+
fig = px.line(df_contr_marg, y='dual', x='t',title='Deckungsbeitrag [€]', color='i', range_y=[0,350], color_discrete_map=color_dict)
|
334 |
with colb2:
|
335 |
fig
|
336 |
|
|
|
338 |
|
339 |
# curtailment
|
340 |
df_curtailment = m.solution['y_curt'].sel(i = iRes).to_dataframe().reset_index()
|
341 |
+
fig = px.area(m.solution['y_curt'].sel(i = iRes).to_dataframe().reset_index(), y='y_curt', x='t', title='Abregelung [MWh]', color='i', color_discrete_map=color_dict)
|
342 |
fig.update_traces(line=dict(width=0))
|
343 |
fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
|
344 |
|
|
|
347 |
|
348 |
# %%
|
349 |
df_charging = m.solution['y_ch'].sel(i = iSto).to_dataframe().reset_index()
|
350 |
+
fig = px.area(m.solution['y_ch'].sel(i = iSto).to_dataframe().reset_index(), y='y_ch', x='t', title='Speicherbeladung [MWh]', color='i', color_discrete_map=color_dict)
|
351 |
fig.update_traces(line=dict(width=0))
|
352 |
fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
|
353 |
|
|
|
356 |
|
357 |
# %%
|
358 |
df_h2_prod = m.solution['y_h2'].sel(i = iPtG).to_dataframe().reset_index()
|
359 |
+
fig = px.area(m.solution['y_h2'].sel(i = iPtG).to_dataframe().reset_index(), y='y_h2', x='t', title='Produktion Wasserstoff [MWh_th]', color='i', color_discrete_map=color_dict)
|
360 |
fig.update_traces(line=dict(width=0))
|
361 |
fig.for_each_trace(lambda trace: trace.update(fillcolor = trace.line.color))
|
362 |
|
|
|
402 |
# Create a Pandas Excel writer using XlsxWriter as the engine
|
403 |
with pd.ExcelWriter(output, engine='xlsxwriter') as writer:
|
404 |
# Write each DataFrame to a different sheet
|
405 |
+
disaggregate_df(df_total_costs).to_excel(writer, sheet_name='Gesamtkosten', index=False)
|
406 |
+
disaggregate_df(df_CO2_price).to_excel(writer, sheet_name='CO2 Preis', index=False)
|
407 |
+
disaggregate_df(df_price).to_excel(writer, sheet_name='Preise', index=False)
|
408 |
+
disaggregate_df(df_contr_marg).to_excel(writer, sheet_name='Deckungsbeiträge', index=False)
|
409 |
+
disaggregate_df(df_new_capacities).to_excel(writer, sheet_name='Kapazitäten', index=False)
|
410 |
+
disaggregate_df(df_production).to_excel(writer, sheet_name='Produktion', index=False)
|
411 |
+
disaggregate_df(df_charging).to_excel(writer, sheet_name='Ladevorgänge', index=False)
|
412 |
+
disaggregate_df(D_t.to_dataframe().reset_index()).to_excel(writer, sheet_name='Nachfrage', index=False)
|
413 |
+
disaggregate_df(df_curtailment).to_excel(writer, sheet_name='Abregelung', index=False)
|
414 |
+
disaggregate_df(df_h2_prod).to_excel(writer, sheet_name='H2 produktion', index=False)
|
415 |
|
416 |
with col4:
|
417 |
st.download_button(
|
418 |
+
label="Download Excel Arbeitsmappe Ergebnisse",
|
419 |
data=output.getvalue(),
|
420 |
+
file_name="Arbeitsmappe_Ergebnisse.xlsx",
|
421 |
mime="application/vnd.ms-excel"
|
422 |
)
|
423 |
|