# -*- coding: utf-8 -*-
# Copyright 2016-2018 Europa-Universität Flensburg,
# Flensburg University of Applied Sciences,
# Centre for Sustainable Energy Systems
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
# File description
"""This module contains functions for storage units.
"""
import io
import os
import logging
logger = logging.getLogger('ego')
if not 'READTHEDOCS' in os.environ:
import pandas as pd
import numpy as np
from etrago.tools.utilities import geolocation_buses
__copyright__ = ("Europa-Universität Flensburg, "
"Centre for Sustainable Energy Systems")
__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)"
__author__ = "wolf_bunke,maltesc"
[docs]def etrago_storages(network):
"""Sum up the pysical storage values of the total scenario based on
eTraGo results.
Parameters
----------
network : :class:`etrago.tools.io.NetworkScenario`
eTraGo ``NetworkScenario`` based on PyPSA Network. See also
`pypsa.network <https://pypsa.org/doc/components.html#network>`_
Returns
-------
results : :pandas:`pandas.DataFrame<dataframe>`
Summarize and returns a ``DataFrame`` of the storage optimaziation.
Notes
-----
The ``results`` dataframe incluedes following parameters:
charge : numeric
Quantity of charged energy in MWh over scenario time steps
discharge : numeric
Quantity of discharged energy in MWh over scenario time steps
count : int
Number of storage units
p_nom_o_sum: numeric
Sum of optimal installed power capacity
"""
if len(network.storage_units_t.p.sum()) > 0:
charge = network.storage_units_t.\
p[network.storage_units_t.p[network.
storage_units[network.storage_units.
p_nom_opt > 0].index].
values > 0.].groupby(network.storage_units.
carrier, axis=1).sum().sum()
discharge = network.storage_units_t.p[network.storage_units_t.
p[network.
storage_units[
network.storage_units.
p_nom_opt > 0].
index].values < 0.].\
groupby(network.storage_units.carrier, axis=1).sum().sum()
count = network.storage_units.bus[network.storage_units.p_nom_opt > 0].\
groupby(network.storage_units.carrier, axis=0).count()
p_nom_sum = network.storage_units.p_nom.groupby(network.storage_units.
carrier, axis=0).sum()
p_nom_o_sum = network.storage_units.p_nom_opt.groupby(
network.storage_units.
carrier, axis=0).sum()
p_nom_o = p_nom_sum - p_nom_o_sum # Zubau
results = pd.concat([charge.rename('charge'),
discharge.rename('discharge'),
p_nom_sum, count.rename('total_units'), p_nom_o
.rename('extension'), ], axis=1, join='outer')
else:
logger.info("No timeseries p for storages!")
results = None
return results
[docs]def etrago_storages_investment(network, json_file, session):
"""Calculate storage investment costs of eTraGo
Parameters
----------
network : :class:`etrago.tools.io.NetworkScenario`
eTraGo ``NetworkScenario`` based on PyPSA Network. See also
`pypsa.network <https://pypsa.org/doc/components.html#network>`_
Returns
-------
storage_costs : numeric
Storage costs of selected snapshots in [EUR]
"""
# check spelling of storages and storage
logger.info(json_file['eTraGo']['extendable'])
stos = 'storage'
# check settings for extendable
if stos not in json_file['eTraGo']['extendable']:
logger.info("The optimizition was not using parameter "
" 'extendable': storage"
"No storage expantion costs from etrago")
if stos in json_file['eTraGo']['extendable']:
network = geolocation_buses(network, session)
# get v_nom
_bus = pd.DataFrame(network.buses[['v_nom', 'country_code']])
_bus.index.name = "name"
_bus.reset_index(level=0, inplace=True)
_storage = network.storage_units[
network.storage_units.p_nom_extendable == True]
_storage.reset_index(level=0, inplace=True)
# provide storage installation costs per voltage level
installed_storages = \
pd.merge(_storage, _bus, left_on='bus', right_on='name')
installed_storages['investment_costs'] = (installed_storages.
capital_cost *
installed_storages.p_nom_opt)
# add voltage_level
installed_storages['voltage_level'] = 'unknown'
ix_ehv = installed_storages[installed_storages['v_nom'] >= 380].index
installed_storages.set_value(ix_ehv, 'voltage_level', 'ehv')
ix_hv = installed_storages[(installed_storages['v_nom'] <= 220) &
(installed_storages['v_nom'] >= 110)].index
installed_storages.set_value(ix_hv, 'voltage_level', 'hv')
# add country differentiation
installed_storages['differentiation'] = 'none'
for idx, val in installed_storages.iterrows():
check = val['country_code']
if "DE" in check:
installed_storages['differentiation'][idx] = 'domestic'
if "DE" not in check:
installed_storages['differentiation'][idx] = 'foreign'
storages_investment = installed_storages[
['voltage_level', 'investment_costs',
'differentiation']].groupby(['differentiation',
'voltage_level']
).sum().reset_index()
storages_investment = storages_investment.\
rename(columns={'investment_costs': 'capital_cost'})
return storages_investment