#!/usr/bin/env python
# coding: utf-8
# #
Abschlussworkshop open_eGo 30. Okt. 2018
# ## Session
#
# In[1]:
__copyright__ = "Reiner Lemoine Institut gGmbH"
__license__ = "GNU Affero General Public License Version 3 (AGPL-3.0)"
__url__ = "https://github.com/openego/eDisGo/blob/master/LICENSE"
__author__ = "nesnoj"
# **Wichtige Links**
#
# * __[DINGO Source Code](https://github.com/openego/ding0)__
# * __[DINGO Documentation](http://dingo.readthedocs.io)__
# * __[open_eGo Projekt-Website](https://openegoproject.wordpress.com)__
# * __[Ergebnisse des Workshops](https://openegoproject.wordpress.com/ergebnisse/)__
#
# # Inhalt
#
# * [1 Einstieg](#einstieg)
# * [2 Annahmen anpassen](#annahmen)
# * [3 Datenbankverbindung aufbauen](#db)
# * [4 DINGO ausführen](#dingo)
# * [5 DINGO ausführen - en Detail](#dingo-detail)
# * [6 Ergebnisse](#results)
# * [7 In DINGOs Datenmodell arbeiten](#use-dingo)
# * [8 Netz exportieren](#export)
# # 1 Einstieg
#
# DINGO (**DI**stribution **N**etwork **G**enerat**O**r) generiert synthetische Verteilnetze auf der Mittel -und Niederspannungsebene.
#
# Für das vorliegende Notebook wird DINGO in der Version 0.1.10 benötigt. Für die Erstellung werden Daten von der [OpenEnergy Platform](https://openenergy-platform.org/) (OEP) benötigt.
#
# **Anmerkung zum Plotting:** Optional: Damit in den Plots eine Hintergrundkarte geladen werden kann, wird das Paket `contextily` benötigt, welches nicht in den erforderlichen Paketen der `setup.py` enthalten ist (Installation per `pip install contextily`).
#
# Mit `%%capture` kann DINGOs Ausgabe in diesem Notebook zugunsten der Übersichtlichkeit unterdrückt werden (auskommentieren, um alle Ausgaben anzuzeigen).
# In[2]:
get_ipython().run_cell_magic('capture', '', "\nfrom ding0.core import NetworkDing0\nfrom ding0.tools.logger import setup_logger\nfrom ding0.tools.results import save_nd_to_pickle\nfrom ding0.tools.plots import plot_mv_topology\nfrom egoio.tools import db\nfrom sqlalchemy.orm import sessionmaker\nimport oedialect\n\n# create new network\nnd = NetworkDing0(name='network')\n# set ID of MV grid district\nmv_grid_districts = [460]\n")
# # 2 Annahmen anpassen
# DINGO verfügt über einen [config-Ordner](https://github.com/openego/ding0/tree/master/ding0/config), in dem alle relevanten Konfigurationen vorgenommen werden können. Hierzu zählen beispielsweise die zu verwendenden DB-Tabellen auf der OEP, Betriebsmittel und zulässige Spannungsbänder.
# Die Konfiguration wird beim Start ausgelesen und in die `NetworkDing0`-Instanz geschrieben.
#
# Die Konfiguration umfasst:
# In[3]:
for key, cfg in nd.config.items():
print('[ {k} ]'.format(k=key))
for param, val in cfg.items():
print(' {k}: {v}'.format(k=param, v=val))
# # 3 Datenbankverbindung aufbauen
# DINGO verwendet Module des [ego.io](https://github.com/openego/ego.io)-Package für den Zugriff auf die OpenEnergy Platform. Für den hier verwendeten Lesebetrieb ist kein Account auf der OEP erforderlich.
#
# (Für Schreibzugriffe wird hingegen ein Account benötigt. `section` bezieht sich auf die Sektion in der ego.io-Konfiguration, in welcher die Verbindung konfiguriert wird.)
# In[4]:
engine = db.connection(section='oedb_dialect')
session = sessionmaker(bind=engine)()
# # 4 DINGO ausführen
# DINGO kann in einem Schritt ausgeführt werden, in dem die entsprechende Methode von `NetworkDing0` aufgerufen wird:
# In[5]:
#nd.run_ding0(session=session,
# mv_grid_districts_no=mv_grid_districts)
# Stattdessen wollen wir jedoch ein wenig ins Detail gehen:
# # 5 DINGO ausführen - en Detail
# Einzelschritte der Methode [`NetworkDing0.run_ding0()`](https://github.com/openego/ding0/blob/master/ding0/core/__init__.py#L105)
# ## 5.1 Daten importieren
# In[6]:
nd.import_mv_grid_districts(session,
mv_grid_districts_no=mv_grid_districts)
nd.import_generators(session)
# ## 5.2 Netze parametrieren und Import validieren
# In[7]:
nd.mv_parametrize_grid()
nd.validate_grid_districts()
# ## 5.3 NS-Netze generieren
# In[8]:
nd.build_lv_grids()
# ## 5.4 MS-Netze generieren
# In[9]:
nd.mv_routing()
# In[10]:
grid = nd._mv_grid_districts[0].mv_grid
# enable jupyter interactive plotting
get_ipython().run_line_magic('matplotlib', 'inline')
import matplotlib
matplotlib.rcParams['figure.figsize'] = (8, 8)
matplotlib.rcParams['figure.dpi'] = 300
# In[11]:
plot_mv_topology(grid, subtitle='Routing completed')
# ## 5.5 Erzeuger anschließen
# In[12]:
nd.connect_generators()
nd.set_branch_ids()
nd.set_circuit_breakers()
# In[13]:
plot_mv_topology(grid, subtitle='Generators connected')
# ## 5.6 Komplexe Lastflussberechnung durchführen
# In[14]:
nd.control_circuit_breakers(mode='open')
nd.run_powerflow(session)
# In[15]:
plot_mv_topology(grid, subtitle='PF result (load case)',
line_color='loading', node_color='voltage', testcase='load')
# In[16]:
plot_mv_topology(grid, subtitle='PF result (feedin case)',
line_color='loading', node_color='voltage', testcase='feedin')
# ## 5.7 MS-Netze verstärken
# In[17]:
nd.reinforce_grid()
# # 6 Ergebnisse
# In[18]:
plot_mv_topology(grid, subtitle='PF result (load case)',
line_color='loading', node_color='voltage', testcase='load')
# In[19]:
plot_mv_topology(grid, subtitle='PF result (feedin case)',
line_color='loading', node_color='voltage', testcase='feedin')
# # 7 In DINGOs Datenmodell arbeiten
# DINGOs Datenmodell abstrahiert reale Strukturen:
#
# Um dies zu verdeutlichen, sehen wir uns dies top-down an, ausgehend von der `NetworkDing0`-Instanz, die wir eingangs erstellt haben:
# In[20]:
nd
# ### MS-Netzgebiete (MV Grid Districts):
# In[21]:
list(nd.mv_grid_districts())
# ### Das MV Grid District enthält das MS-Netz und die Lastgebiete (LV Load Areas):
# In[22]:
nd._mv_grid_districts[0].mv_grid
# In[23]:
list(nd._mv_grid_districts[0].lv_load_areas())
# ### Die Lastgebiete enthalten jeweils NS-Netzgebiete (LV Grid Districts):
# In[24]:
list(nd._mv_grid_districts[0]._lv_load_areas[0].lv_grid_districts())
# ### Mit jeweils einem NS-Netz:
# In[25]:
nd._mv_grid_districts[0]._lv_load_areas[0]._lv_grid_districts[0].lv_grid
# ### Jedem Netz (MS oder NS) ist ein Graph zugeordnet, der alle Knoten (Stations, Loads, ...) und Kanten (Leitungen) enthält:
# In[26]:
nd._mv_grid_districts[0].mv_grid._graph
# In[27]:
nd._mv_grid_districts[0].mv_grid._graph.nodes()
# In[28]:
nd._mv_grid_districts[0].mv_grid._graph.edges()
# In[29]:
list(nd._mv_grid_districts[0].mv_grid._graph.nodes())[0].__dict__.keys()
# # 8 Netz exportieren
# Im pickle-Format
# In[30]:
nd.control_circuit_breakers(mode='close')
save_nd_to_pickle(nd, filename='ding0_grids__460.pkl')
# Dieses kann anschließend in [eDisGo](https://github.com/openego/eDisGo) importiert werden, um dieses zu analysieren und Netzerweiterungsmaßnahmen durchzuführen.