Skip to content

Commit

Permalink
Merge branch 'features/#261-emob-tests' into features/#276-improve-si…
Browse files Browse the repository at this point in the history
…mple-example
  • Loading branch information
birgits committed Sep 9, 2022
2 parents 3cdd70c + 1db13a4 commit 5d8d459
Show file tree
Hide file tree
Showing 42 changed files with 3,352 additions and 1,398 deletions.
16 changes: 8 additions & 8 deletions doc/api/edisgo.tools.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,6 @@ edisgo.tools.config module
:undoc-members:
:show-inheritance:

edisgo.tools.edisgo\_run module
--------------------------------

.. automodule:: edisgo.tools.edisgo_run
:members:
:undoc-members:
:show-inheritance:

edisgo.tools.geo module
------------------------

Expand All @@ -33,6 +25,14 @@ edisgo.tools.geopandas\_helper module
:undoc-members:
:show-inheritance:

edisgo.tools.logger module
----------------------------------------

.. automodule:: edisgo.tools.logger
:members:
:undoc-members:
:show-inheritance:

edisgo.tools.networkx\_helper module
----------------------------------------

Expand Down
2 changes: 1 addition & 1 deletion doc/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@
"shapely": ("https://shapely.readthedocs.io/en/latest/manual.html#%s", "shapely."),
"ding0": ("https://dingo.readthedocs.io/en/dev/api/ding0.html#%s", "Ding0"),
"pypsa": ("https://pypsa.readthedocs.io/en/latest/components.html#%s", "pypsa"),
"plotly": ("https://plotly.com/python-api-reference/generated/#%s.html", "plotly"),
"plotly": ("https://plotly.com/python-api-reference/generated/%s.html", "plotly"),
}
# Add any paths that contain templates here, relative to this directory.
templates_path = ["_templates"]
Expand Down
54 changes: 27 additions & 27 deletions doc/features_in_detail.rst
Original file line number Diff line number Diff line change
Expand Up @@ -264,57 +264,57 @@ It is also possible to curtail specific generators internally, though a user fri
.. _electromobility-integration-label:

Electromobility integration
--------------------
----------------------------

The import and integration of electromobility data is implemented in :py:func:`~edisgo.io.electromobility_import`.

Allocation of charging demand
^^^^^^^^^^^^^^^^^^^^^^^^
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

The allocation of charging processes to charging stations is implemented in
The allocation of charging processes to charging stations is implemented in
:py:func:`~edisgo.io.electromobility_import.distribute_charging_demand`.
After electromobility data is loaded, the charging demand from SimBEV is allocated to potential charging parks
from TracBEV. The allocation of the charging processes to the charging infrastructure is carried out with the
help of the weighting factor of the potential charging parks determined by TracBEV. This involves a random and
After electromobility data is loaded, the charging demand from SimBEV is allocated to potential charging parks
from TracBEV. The allocation of the charging processes to the charging infrastructure is carried out with the
help of the weighting factor of the potential charging parks determined by TracBEV. This involves a random and
weighted selection of one charging park per charging process. In the case of private charging infrastructure, a
separate charging point is set up for each EV. All charging processes of the respective EV and charging use case
are assigned to this charging point. The allocation of private charging processes to charging stations is
separate charging point is set up for each electric vehicle (EV). All charging processes of the respective EV and charging use case
are assigned to this charging point. The allocation of private charging processes to charging stations is
implemented in :py:func:`~edisgo.io.electromobility_import.distribute_private_charging_demand`.

For the public charging infrastructure, the allocation is made explicitly per charging process. For each charging
process it is determined whether a suitable charging point is already available. For this purpose it is checked
if the charging point is occupied by another EV in the corresponding period and whether it can provide the
corresponding charging capacity. If no suitable charging point is available, a charging point is determined
randomly and weighted in the same way as for private charging. The allocation of public charging processes to
For public charging infrastructure, the allocation is made explicitly per charging process. For each charging
process it is determined whether a suitable charging point is already available. For this purpose it is checked
whether the charging point is occupied by another EV in the corresponding period and whether it can provide the
corresponding charging capacity. If no suitable charging point is available, a charging point is determined
randomly and weighted in the same way as for private charging. The allocation of public charging processes to
charging stations is implemented in :py:func:`~edisgo.io.electromobility_import.distribute_public_charging_demand`.

.. _charging_strategies-label:

Charging strategies
^^^^^^^^^^^^^^^^^^^^^^^^

eDisGo right now provides three charging strategy methodologies called 'dumb', 'reduced' and 'residual', that
are implemented in :py:mod:`~edisgo.flex_opt.charging_strategies`.
The aim of the charging strategies is to generate the most grid-friendly charging behavior possible without
restricting the convenience for end users. Therefore, the boundary condition of all charging strategies is that
the charging requirement of each charging process must be fully covered. This means that charging processes can
only be used as a flexibility if the EV can be fully charged while it is stationary. Furthermore, only private
charging processes can be used as a flexibility, since the fulfillment of the service is the priority for public
charging processes. In order to be able to evaluate the three charging strategies, a reference charging strategy
is also examined.
eDisGo right now provides three charging strategy methodologies called 'dumb', 'reduced' and 'residual', that
are implemented in :py:mod:`~edisgo.flex_opt.charging_strategies`.
The aim of the charging strategies 'reduced' and 'residual' is to generate the most grid-friendly charging behavior possible without
restricting the convenience for end users. Therefore, the boundary condition of all charging strategies is that
the charging requirement of each charging process must be fully covered. This means that charging processes can
only be flexibilised if the EV can be fully charged while it is stationary. Furthermore, only private
charging processes can be used as a flexibility, since the fulfillment of the service is the priority for public
charging processes.

'dumb'
""""""""""""""""""
Is the default charging strategy and corresponds to the reference charging.
The cars are charged directly after arrival with the maximum possible charging capacity.
In this charging strategy the cars are charged directly after arrival with the maximum possible charging capacity.

'reduced'
""""""""""""""""""
Is a preventive charging strategy. The cars are charged directly after arrival with the minimum possible
charging power. The minimum possible charging power is determined by the parking time and the parameter
This is a preventive charging strategy. The cars are charged directly after arrival with the minimum possible
charging power. The minimum possible charging power is determined by the parking time and the parameter
minimum_charging_capacity_factor.

'residual'
""""""""""""""""""
Is an active charging strategy. The cars are charged when the residual load in the MV grid is lowest
This is an active charging strategy. The cars are charged when the residual load in the MV grid is lowest
(high generation and low consumption). Charging processes with a low flexibility are given priority.


Expand Down
64 changes: 33 additions & 31 deletions doc/usage_details.rst
Original file line number Diff line number Diff line change
Expand Up @@ -266,7 +266,8 @@ The charging strategies can be invoked as follows:
edisgo.apply_charging_strategy()
See :attr:`~.edisgo.EDisGo.apply_charging_strategy` for more information.
See function docstring of :attr:`~.edisgo.EDisGo.apply_charging_strategy` or
documentation section :ref:`charging_strategies-label` for more information.

Reactive power time series
^^^^^^^^^^^^^^^^^^^^^^^^^^
Expand Down Expand Up @@ -349,27 +350,24 @@ Further information on the grid reinforcement methodology can be found in sectio
Electromobility
-----------------

Electromobility data including charging processes necessary to apply different
charging strategies, as well as information on potential charging sites and
integrated charging parks can be integrated into the grid and are stored in
the :pandas:`pandas.DataFrames<DataFrame>` or :geopandas:`GeoDataFrame` in the
Electromobility data including charging processes as well as information on potential charging sites and
integrated charging parks are stored in the
:class:`~.network.electromobility.Electromobility` object.

You can access those dataframes/geodataframes as follows:
You can access these data as follows:

.. code-block:: python
# Access DataFrame with all SimBEV charging processes.
# Access DataFrame with all SimBEV charging processes
edisgo.electromobility.charging_processes_df
# Access GeoDataFrame with all TracBEV potential charging parks.
# Access GeoDataFrame with all TracBEV potential charging parks
edisgo.electromobility.potential_charging_parks_gdf
# Access DataFrame with all charging parks that got integrated.
# Access DataFrame with all charging parks that got integrated
edisgo.electromobility.integrated_charging_parks_df
The integrated charging points are then also stored in the
:pandas:`pandas.DataFrames<DataFrame>` in the :class:`~.network.topology.Topology`
The integrated charging points are also stored in the :class:`~.network.topology.Topology`
object and can be accessed as follows:

.. code-block:: python
Expand All @@ -378,21 +376,23 @@ object and can be accessed as follows:
edisgo.topology.charging_points_df
So far, adding electormobility data to an eDisGo object requires electromobility
So far, adding electromobility data to an eDisGo object requires electromobility
data from `SimBEV <https://github.com/rl-institut/simbev>`_ (required version:
`3083c5a <https://github.com/rl-institut/simbev/commit/
86076c936940365587c9fba98a5b774e13083c5a>`_)
86076c936940365587c9fba98a5b774e13083c5a>`_)
and `TracBEV <https://github.com/rl-institut/tracbev>`_ (required version:
`14d864c <https://github.com/rl-institut/tracbev/commit/
03e335655770a377166c05293a966052314d864c>`_) to be stored in the directories
specified through the parameters simbev_directory and tracbev_directory.
SimBEV provides data on standing times, charging demand, etc. per vehicle,
03e335655770a377166c05293a966052314d864c>`_) to be stored in the directories
specified through the parameters simbev_directory and tracbev_directory.
SimBEV provides data on standing times, charging demand, etc. per vehicle,
whereas TracBEV provides potential charging point locations.

.. todo:: Add information on how to retrieve SimBEV and TracBEV data

Here is a small examples on how to import electromobility data and apply a
charging strategy to the charging processes.
Here is a small example on how to import electromobility data and apply a
charging strategy. A more extensive example can be found in
the example jupyter notebook
`electromobility_example <https://github.com/openego/eDisGo/blob/dev/examples/electromobility_example.ipynb>`_.

.. code-block:: python
Expand All @@ -407,25 +407,27 @@ charging strategy to the charging processes.
)
edisgo.set_time_series_active_power_predefined(
fluctuating_generators_ts="oedb",
dispatchable_generators_ts=pd.DataFrame(data=1, columns=["other"], index=timeindex),
dispatchable_generators_ts=pd.DataFrame(
data=1, columns=["other"], index=timeindex),
conventional_loads_ts="demandlib",
)
edisgo.set_time_series_reactive_power_control()
# Resample edisgo timeseries to 15-minute resolution to match simBEV and tracBEV data
# Resample edisgo timeseries to 15-minute resolution to match with SimBEV and
# TracBEV data
edisgo.resample_timeseries()
# Import electromobility data
edisgo.import_electromobility(
simbev_directory=simbev_path,
tracbev_directory=tracbev_path,
)
# Apply charging strategy
edisgo.apply_charging_strategy(strategy="dumb")
Further information on the electromobility integration methodology and the charging
Further information on the electromobility integration methodology and the charging
strategies can be found in section :ref:`electromobility-integration-label`.


Expand Down Expand Up @@ -565,18 +567,18 @@ line loading and node voltages in the MV grid or as a histograms.
# plot voltage histogram
edisgo.histogram_voltage()
# draw a plotly html figure
draw_plotly(edisgo)
# plot relative loading and voltage deviation, with grid coordinates
# plot relative loading and voltage deviation, with grid coordinates
# modified to have the station in the origin
draw_plotly(
edisgo, G=edisgo_obj.topology.mv_grid.graph,
line_color="relative_loading", node_color="voltage_deviation",
edisgo, G=edisgo_obj.topology.mv_grid.graph,
line_color="relative_loading", node_color="voltage_deviation",
grid=edisgo.topology.mv_grid
)
See :class:`~.EDisGo` class for more plots and plotting options.

Results
Expand Down
2 changes: 2 additions & 0 deletions doc/whatsnew/v0-2-0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ Changes
* added pre-commit hooks (flake8, black, isort, pyupgrade) `#229 <https://github.com/openego/eDisGo/pull/229>`_
* added issue and pull request templates `#220 <https://github.com/openego/eDisGo/issues/220>`_
* added Windows installation yml and documentation
* added functionality to set up different loggers with individual logging levels and where to write output `#295 <https://github.com/openego/eDisGo/issues/295>`_
* added integrity checks of eDisGo object `#231 <https://github.com/openego/eDisGo/issues/231>`_
* added functionality to save to and load from zip archive `#216 <https://github.com/openego/eDisGo/pull/216>`_
* added option to not raise error in case power flow did not converge `#207 <https://github.com/openego/eDisGo/issues/207>`_
* added pyplot `#214 <https://github.com/openego/eDisGo/pull/214>`_
* added functionality to create geopandas dataframes `#224 <https://github.com/openego/eDisGo/issues/224>`_
* added functionality to resample time series `#269 <https://github.com/openego/eDisGo/pull/269>`_
* added tests
* major refactoring of loads and time series

Expand Down
3 changes: 2 additions & 1 deletion edisgo/config/config_grid_expansion_default.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@
# Standard equipment for grid expansion measures. Source: Rehtanz et. al.: "Verteilnetzstudie für das Land Baden-Württemberg", 2017.
hv_mv_transformer = 40 MVA
mv_lv_transformer = 630 kVA
mv_line = NA2XS2Y 3x1x185 RM/25
mv_line_10kv = NA2XS2Y 3x1x185 RM/25
mv_line_20kv = NA2XS2Y 3x1x240
lv_line = NAYY 4x1x150

[grid_expansion_allowed_voltage_deviations]
Expand Down
54 changes: 35 additions & 19 deletions edisgo/edisgo.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ class EDisGo:
def __init__(self, **kwargs):

# load configuration
self._config = Config(config_path=kwargs.get("config_path", None))
self._config = Config(config_path=kwargs.get("config_path", "default"))

# instantiate topology object and load grid data
self.topology = Topology(config=self.config)
Expand Down Expand Up @@ -2039,30 +2039,46 @@ def check_integrity(self):

def resample_timeseries(self, method: str = "ffill", freq: str = "15min"):
"""
Returns timeseries resampled from hourly resolution to 15 minute resolution.
Resamples all generator, load and storage time series to a desired resolution.
Parameters
----------
method : str, optional
Method to choose from to fill missing values when upsampling. Possible
options are:
The following time series are affected by this:
* :attr:`~.network.timeseries.TimeSeries.generators_active_power`
* :attr:`~.network.timeseries.TimeSeries.loads_active_power`
* :attr:`~.network.timeseries.TimeSeries.storage_units_active_power`
* 'ffill': propagate last valid observation forward to next valid
observation. See
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.ffill.html
'ffill' is the Default.
* :attr:`~.network.timeseries.TimeSeries.generators_reactive_power`
* 'bfill': use next valid observation to fill gap. See
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.bfill.html
* :attr:`~.network.timeseries.TimeSeries.loads_reactive_power`
* 'interpolate': Fill NaN values using an interpolation method. See
https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.interpolate.html
* :attr:`~.network.timeseries.TimeSeries.storage_units_reactive_power`
Both up- and down-sampling methods are possible.
Parameters
----------
method : str, optional
Method to choose from to fill missing values when resampling.
Possible options are:
* 'ffill'
Propagate last valid observation forward to next valid
observation. See :pandas:`pandas.DataFrame.ffill<DataFrame.ffill>`.
* 'bfill'
Use next valid observation to fill gap. See
:pandas:`pandas.DataFrame.bfill<DataFrame.bfill>`.
* 'interpolate'
Fill NaN values using an interpolation method. See
:pandas:`pandas.DataFrame.interpolate<DataFrame.interpolate>`.
Default: 'ffill'.
freq : str, optional
Frequency that timeseries is resampled to. Can be any frequency up to one
hour. Offset aliases can be found here:
https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases
15 minutes is the default.
Frequency that time series is resampled to. Offset aliases can be found
here:
https://pandas.pydata.org/pandas-docs/stable/user_guide/timeseries.html#offset-aliases.
Default: '15min'.
"""
self.timeseries.resample_timeseries(method=method, freq=freq)
Expand Down
20 changes: 10 additions & 10 deletions edisgo/equipment/equipment-parameters_LV_cables.csv
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
name,U_n,I_max_th,R_per_km,L_per_km
#-,kV,kA,ohm/km,mH/km
NAYY 4x1x300,0.4,0.419,0.1,0.279
NAYY 4x1x240,0.4,0.364,0.125,0.254
NAYY 4x1x185,0.4,0.313,0.164,0.256
NAYY 4x1x150,0.4,0.275,0.206,0.256
NAYY 4x1x120,0.4,0.245,0.253,0.256
NAYY 4x1x95,0.4,0.215,0.320,0.261
NAYY 4x1x50,0.4,0.144,0.449,0.270
NAYY 4x1x35,0.4,0.123,0.868,0.271
name,U_n,I_max_th,R_per_km,L_per_km,C_per_km
#-,kV,kA,ohm/km,mH/km,uF/km
NAYY 4x1x300,0.4,0.419,0.1,0.279,0
NAYY 4x1x240,0.4,0.364,0.125,0.254,0
NAYY 4x1x185,0.4,0.313,0.164,0.256,0
NAYY 4x1x150,0.4,0.275,0.206,0.256,0
NAYY 4x1x120,0.4,0.245,0.253,0.256,0
NAYY 4x1x95,0.4,0.215,0.320,0.261,0
NAYY 4x1x50,0.4,0.144,0.449,0.270,0
NAYY 4x1x35,0.4,0.123,0.868,0.271,0
2 changes: 1 addition & 1 deletion edisgo/flex_opt/charging_strategies.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
],
}

logger = logging.getLogger("edisgo")
logger = logging.getLogger(__name__)


# TODO: the dummy timeseries should be as long as the simulated days and not
Expand Down
Loading

0 comments on commit 5d8d459

Please sign in to comment.