Commit fc3ff65c authored by Marc Michael Bumann's avatar Marc Michael Bumann
Browse files

Upload New File

parent 3ba71ac7
{"cells":[{"metadata":{},"cell_type":"markdown","source":"# Aufgabe für die Projektgruppe 4"},{"metadata":{},"cell_type":"markdown","source":"Bearbeiten Sie die folgende Aufgabe:\n\nIhr Auftraggeber ist eine Familie, welche eine Beratung von Ihnen benötigt. Sie besitzt ein kleines altes Windrad, welches nur für den Eigenverbrauch genutzt wird sowie eine PV Anlage. Die Familie möchte von Ihnen wissen, ob Sie Kosten durch die Investition in verschiedene Komponenten ihres Energiesystems einsparen kann. \n\nNehmen Sie dabei die folgenden Angaben an:\n* Nennleistung der Windernergieanlage: 5 kW (Keine EEG- Vergütung)\n* Nennleistung der PV-Anlage 9 kWp (70% Kappungsgrenze berücksichtigen)\n* Die Anschlussleistung an das elektrische Netz beträgt 15 kW\n* Die Heizleistung des Erdgaskessel liegt bei 20 kW, der Wirkungsgrad ist 99%\n* Erdgaspreis: 7 cent/kWh\n* Strompreis: 30 cent/kWh\n* EEG-Vergütung PV Anlage: 12,30 cent/kWh\n\nPrüfen und kombinieren Sie mindestens drei der unten aufgeführten Optionen und bewerten Sie diese nach ihrer wirtschaftlicher Vorteilhaftigkeit. Unter den gewählten Optionen sollte sich mindestens eine der beiden Optionen BHKW oder Wärmepumpe befinden:\n- Implementierung eines Heizstabes mit annuitätische Kosten von 50€ (Elektrische Leistung 5 kW, Wirkungsgrad 98%) \n- Installation eines BHKWs mit annuitätische Kosten von 1.200€ (Elektrische Leistung 1kW, elektrischer Wirkungsgrad 16%, Thermischer Wirkungsgrad 80%, nehmen Sie eine feste Stromkennzahl von 0,2 an, ein Beispiel für die Implementierung eines BHKWs in PyPSA finden Sie hier: https://pypsa.org/examples/chp-fixed-heat-power-ratio.html. Eine KWK-Vergütung müssen Sie nicht implementieren, da hier die pauschalierte Zuschlagzahlung gewählt wird.)\n- Beschaffung einer elektrischen Batterie mit annuitätische Kosten von 900€ (8kWh Kapazität, 2,4 kW Speicher und Ladeleistung, einem Gesamtwirkungsgrad von 85%, keine Selbstentladungsverluste) \n- Erweiterung des Heizungssystems um einen thermischen Speicher mit annuitätische Kosten von 100€ (7kWh Kapazität und eine Ein und Ausspeicherleistung von 12 kW, keine Selbstentladungsverluste)\n- Implementierung einer selbst gewählten Wärmepumpe. Hier müssen Sie nach geeigneten Daten zu Leistungen, Kosten und Performance recherchieren. Sie dürfen dabei die Jahresarbeitszahl als konstanten COP annehmen. Gehen Sie weiter davon aus, dass der Annuitätenfaktor für eine solche Investition bei 0,117 liegt.\n\n1) Formulieren Sie die Optimierungsaufgabe\n2) Skizzieren Sie das heutige System und bestimmen Sie die Kosten.\n3) Skizzieren Sie mögliche Erweiterungen und bestimmen Sie die Kosten.\n4) Interpretieren Sie die ihre Ergebnisse und ziehen Sie Schlussfolgerungen.\n5) Bestimmen Sie die Grenzen Ihrer Modellierung und begründen Sie, ob die Ergebnisse trotz der Beschränkungen valide sind.\n\nDer Import der Lastzeitreihen und der Einspeisezeitreihen ist unten schon vorbereitet. Diese repräsentieren das Jahr 2018 in stündlicher Auflösung. Nutzen Sie das in der Übung besprochene JupyterNotebook und schauen Sie sich die Funktionen und den Code dort an, um Ihr Energiesystem aufzubauen, es zu simulieren und auszuwerten. "},{"metadata":{},"cell_type":"markdown","source":"# Import <a class=\"anchor\" id=\"chapter1\"></a>"},{"metadata":{},"cell_type":"markdown","source":"## Import der benötigten Python Module <a class=\"anchor\" id=\"section_1_1\"></a>"},{"metadata":{"trusted":true},"cell_type":"code","source":"import pypsa\nimport pandas as pd\nimport math\nimport numpy as np","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"## Import der Daten <a class=\"anchor\" id=\"section_1_2\"></a>"},{"metadata":{},"cell_type":"markdown","source":"Die Werte der Zeitreihen sind in einem Unterordner \"data\" als csv-Datein abgelegt. Sie bilden das Jahr 2019 ab und werden mithilfe des Python Moduls pandas eingelesen und als Variablen angelegt. Dabei werden Parameter wie der Separator (hier \";\") und die Indexspalte sowie die Funktion, aus der Indexspalte Zeit und Datenformate auszulesen gesetzt."},{"metadata":{"trusted":true},"cell_type":"code","source":"pv_infeed = pd.read_csv('./data/pv_infeed.csv', sep = ',', skiprows =3, index_col='time', parse_dates=True)\nwind_infeed = pd.read_csv('./data/wind_infeed.csv', sep = ',', skiprows =3, index_col='time', parse_dates=True)","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"electrical_load = pd.read_csv('./data/SumProfiles_3600s.Electricity.csv', sep = ';', index_col='time', parse_dates=True)\nthermal_load = pd.read_csv('./data/SumProfiles_3600s.Gas.csv', sep = ';', index_col='time', parse_dates=True)\n","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Die eingelesenen Zeitreihen sind so noch nicht vollständig nutzbar. Um die Einspeisung der Wind und PV-Anlage zu normieren wird eine neue Spalte mit dem normierten Leistungsoutput sowie neue Spalten mit der Leistung der Last in den jeweiligen Variablen angelegt."},{"metadata":{"trusted":true},"cell_type":"code","source":"#Die gemessene PV-Einspeiseganglinie ist von einer Anlage mit einer Leistung von 9 kWp, die der Windenergieanlage mit 5 kW.\npv_infeed['p_max_pu'] = pv_infeed.electricity/9 \nwind_infeed['p_max_pu'] = wind_infeed.electricity/5 ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"Um einen kurzen Einblick in die Daten zu erhalten, schauen wir uns alle vier Tabellen an:"},{"metadata":{"trusted":true},"cell_type":"code","source":"df_figure = pd.concat([electrical_load.sum_kwh, thermal_load.sum_kwh, pv_infeed.electricity,wind_infeed.electricity], axis = 1)\ndf_figure.columns = ['Elektrische Last', 'Thermische Last', 'PV Einspeisung', 'Wind Einspeisung']\ndf_figure.loc['01-01-18 00:00:00':'12-31-18 23:00:00'].plot(subplots = True, figsize=(15,10), title= 'Leistung in kW')","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"# Ab hier können Sie selbst Code schreiben und das Energiesystem simulieren.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Komponenten des Haushaltes"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Windkraft-Anlage\nwind = {\"electrical_power\": 5.0}\n\n# PV-Anlage\npv = {\"electrical_power\": 9.0}\n\n#Erdgaskessel\nheating_boiler = {\"thermal_power\": 15.0,\n \"efficiency\":0.99,# Effizienz als normierte Kennzahl\n \"gas_costs\": 7.0} #Kosten in cent/kWh\n ","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Netzanschluss"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Leistungsbezug aus dem Netz\ngrid_import = {\"electrical_power\" : 15.0,\n \"electricity_price\": 30.0} #Preise in cent/kWh\n\n#Leistungsabgabe in das Netz\ngrid_export = {\"electrical_power\" : 0.7 * pv[\"electrical_power\"], #Repräsentiert die 70% Kappungsgrenze bei kleinen PV-Anlagen\n \"electricity_revenue\": 12.3} #EEG-Erlöse in cent/kWh\n#Muss wind hier noch rein?","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Definition des Netzwerks"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Netzwerk definieren\nnetwork = pypsa.Network()\nnetwork.set_snapshots(pv_infeed.index)\nnetwork.snapshot_weightings = pd.Series(data = 1/6, index = network.snapshots) #Jeder Zeitpunkt repräsentiert 10 Minuten also 1/6 Stunde.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Knoten definieren"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Stromknoten definieren\nnetwork.add(\"Bus\", \n name = \"electricity\")\n\n#Wärmeknoten definieren\nnetwork.add(\"Bus\", \n name = \"thermal\")","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Lasten definieren"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Elektrische Last\nnetwork.add(\"Load\", \n name =\"electricity_load\", \n bus = \"electricity\", \n p_set = electrical_load.power_kw)\n\n# Thermische last\nnetwork.add(\"Load\", \n name =\"thermal_load\", \n bus = \"thermal\", \n p_set = thermal_load.power_kw)","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Erzeugungseinheiten definieren"},{"metadata":{"trusted":true},"cell_type":"code","source":"#PV-Anlage\nnetwork.add(\"Generator\", \n name = \"pv\",\n bus = \"electricity\", \n p_nom = pv[\"electrical_power\"], \n p_max_pu = pv_infeed.p_max_pu, \n marginal_cost = 0)\n\n#Windkraft-Anlage\nnetwork.add(\"Generator\", \n name = \"wind\",\n bus = \"electricity\", \n p_nom = wind[\"electrical_power\"], \n p_max_pu = wind_infeed.p_max_pu, \n marginal_cost = 0)\n\n#Heizkessel\nnetwork.add(\"Generator\", \n name = \"boiler\", \n bus = \"thermal\", \n p_nom = heating_boiler[\"thermal_power\"], efficiency=heating_boiler[\"efficiency\"], \n marginal_cost = heating_boiler[\"gas_costs\"]/heating_boiler[\"efficiency\"])","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Speicher definieren"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Hilfsknoten\nnetwork.add(\"Bus\", \n name = \"storage_thermal\")\n\n#Einspeicherleistung vom Knoten \"thermal\" zum Knoten \"storage_thermal\"\nnetwork.add(\"Link\", \n name = \"hot_water_storage_charge\", \n bus0 = \"thermal\", \n bus1 = \"storage_thermal\", \n p_nom = hot_water_storage[\"thermal_power\"])\n\n#Ausspeicherleistung vom Knoten \"storage_thermal\" zum Knoten \"thermal\"\nnetwork.add(\"Link\", \n name = \"hot_water_storage_discharge\", \n bus0 = \"storage_thermal\", \n bus1 = \"thermal\", \n p_nom = hot_water_storage[\"thermal_power\"])\n\n#Speicher\nnetwork.add(\"Store\", \n name = \"hot_water_storage\", \n bus = \"storage_thermal\", \n e_nom = hot_water_storage[\"thermal_capacity\"],\n e_cyclic = True, # Der Speicherfüllstand soll am Ende des Betrachtungszeitraumes wieder den Wert vom Anfang annehmen\n standing_loss = hot_water_storage[\"standing_loss\"]\n )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"markdown","source":"# Netzanschluss definieren"},{"metadata":{"trusted":true},"cell_type":"code","source":"#Netzbezug\nnetwork.add(\"Generator\", \n name = \"grid_import\",\n bus = \"electricity\", \n p_nom = grid_import[\"electrical_power\"], \n marginal_cost = grid_import[\"electricity_price\"])\n\n#Netzeinspeisung\nnetwork.add(\"Generator\", \n name = \"grid_export\",\n bus = \"electricity\", \n p_nom = grid_export[\"electrical_power\"], \n marginal_cost = -grid_export[\"electricity_revenue\"], #Die Kosten müssen hier negativ sein, um Erlöse darzustellen\n sign = -1) #Das Vorzeichen -1 sorgt hier dafür, dass der Generator Leistung aufnimmt und nicht abgibt.","execution_count":null,"outputs":[]},{"metadata":{},"cell_type":"markdown","source":"# Basiskonfiguration simulieren"},{"metadata":{"trusted":true},"cell_type":"code","source":"# Simulation der Basiskonfiguration für den kompletten Zeitraum:\nnetwork.lopf(solver_name = \"glpk\", pyomo = False) #Der Parameter pyomo = False hilft uns bei diesem Netzwerk RAM und Rechenzeit zu sparen.","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"#Auswertung der Kosten und Anteile\ndef cost_share_evaluation(network):\n '''\n This function evaluate the solved PyPSA network to get the costs, revenues and the share of the selfconsumption.\n \n Parameters\n ----------\n network: PyPSA Network\n The solved PyPSA network with all corresponding devices\n Returns\n -------\n results : dict\n The dictionary with all the results.\n '''\n \n grid_import = (network.generators_t.p['grid_import'] * network.snapshot_weightings).sum()\n grid_export = (network.generators_t.p['grid_export'] * network.snapshot_weightings).sum()\n self_consumed_pv = (network.generators_t.p['pv'] * network.snapshot_weightings).sum()- grid_export\n self_consumption_ratio = self_consumed_pv/(grid_import + self_consumed_pv)\n \n electricity_cost = grid_import * network.generators.marginal_cost['grid_import']\n electricty_revenues = grid_export * network.generators.marginal_cost['grid_export']\n gas_costs = (network.generators_t.p['boiler']*network.snapshot_weightings).sum() * network.generators.marginal_cost['boiler']\n \n curtailment = ((network.generators_t.p_max_pu['pv']*network.generators.p_nom['pv'] - network.generators_t.p['pv'])*network.snapshot_weightings).sum()\n\n results = {\"Eigenverbrauchsanteil\": self_consumption_ratio,\n \"Stromkosten\": electricity_cost,\n \"Gaskosten\": gas_costs,\n \"Stromerlöse\": -electricty_revenues,\n \"Gesamtkosten\": electricity_cost + gas_costs + electricty_revenues,\n \"Nicht nutzbare Energie\": curtailment}\n results_energy = {'Abregelung': curtailment,\n 'Netzeinspeisung': grid_export,\n 'Eigenverbrauch': self_consumed_pv,\n 'Netzbezug': -grid_import}\n \n return results, results_energy","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"results_base, results_energy_base = cost_share_evaluation(network)\n\n#Die Werte sollen auch als Text ausgegeben werden\nprint(\"Der Eigenverbrauchsanteil am Stromverbrauch in der Basiskonfiguration beträgt \"\n + str(round(results_base[\"Eigenverbrauchsanteil\"]*100,2))\n +\"%. Dabei entstehen Stromkosten von \"\n +str(round(results_base[\"Stromkosten\"]/100,2))\n +\"€, Gaskosten von \"\n +str(round(results_base[\"Gaskosten\"]/100,2))\n +\"€ und EEG-Erlöse von \"\n +str(round(results_base[\"Stromerlöse\"]/100,2))\n +\", wobei \" +str(round(results_base[\"Nicht nutzbare Energie\"]/100,1))+ \"kWh PV-Strom abgeregelt werden muss.\"\n +\" Die Gesamtkosten betragen \"+ str(round(results_base[\"Gesamtkosten\"]/100,2)) +\"€.\"\n )","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"load_figure = network.loads_t.p_set['electricity_load']\nload_figure.name = 'Elektrische Last'\nax = load_figure.loc['10-13-19 00:00:00':'10-14-19 23:50:00'].plot(legend = True, color = 'red')\ndf_figure_base = pd.concat([network.generators_t.p['pv'], network.generators_t.p['grid_import'], -network.generators_t.p['grid_export']], axis = 1)\ndf_figure_base.columns = ['PV Erzeugung', 'Netzbezug', 'Netzeinspeisung']\ndf_figure_base.loc['10-13-19 00:00:00':'10-14-19 23:50:00'].plot(legend =True, subplots = False, figsize=(15,10), kind= 'area', linewidth=0, ax=ax)\n","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]},{"metadata":{"trusted":true},"cell_type":"code","source":"","execution_count":null,"outputs":[]}],"metadata":{"celltoolbar":"Raw Cell Format","kernelspec":{"name":"python3","display_name":"Python 3","language":"python"},"language_info":{"name":"python","version":"3.9.2","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"}},"nbformat":4,"nbformat_minor":4}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment