From b227a9c6426d0f1c8f69d66e2df1904231bfb42a Mon Sep 17 00:00:00 2001 From: Bla Bla Date: Sun, 18 Feb 2024 14:32:27 +0100 Subject: [PATCH] EMS, Akku + erster Testfall (test.py) --- modules/class_akku.py | 40 +++++++++++++++++ modules/class_ems.py | 32 ++++++++++++++ modules/class_pv_forecast.py | 12 ++++++ test.py | 84 ++++++++++++++++++++++++++++++++++++ 4 files changed, 168 insertions(+) create mode 100644 modules/class_akku.py create mode 100644 modules/class_ems.py create mode 100644 test.py diff --git a/modules/class_akku.py b/modules/class_akku.py new file mode 100644 index 0000000..91dddea --- /dev/null +++ b/modules/class_akku.py @@ -0,0 +1,40 @@ +class PVAkku: + def __init__(self, kapazitaet_wh): + # Kapazität des Akkus in Wh + self.kapazitaet_wh = kapazitaet_wh + # Initialer Ladezustand des Akkus in Wh + self.soc_wh = 0 + + def ladezustand_in_prozent(self): + return (self.soc_wh / self.kapazitaet_wh) * 100 + + def energie_abgeben(self, wh): + if self.soc_wh >= wh: + self.soc_wh -= wh + return wh + else: + abgegebene_energie = self.soc_wh + self.soc_wh = 0 + return abgegebene_energie + + def energie_laden(self, wh): + if self.soc_wh + wh <= self.kapazitaet_wh: + self.soc_wh += wh + else: + self.soc_wh = self.kapazitaet_wh + + + +if __name__ == '__main__': + # Beispiel zur Nutzung der Klasse + akku = PVAkku(10000) # Ein Akku mit 10.000 Wh Kapazität + print(f"Initialer Ladezustand: {akku.ladezustand_in_prozent()}%") + + akku.energie_laden(5000) + print(f"Ladezustand nach Laden: {akku.ladezustand_in_prozent()}%, Aktueller Energieinhalt: {akku.aktueller_energieinhalt()} Wh") + + abgegebene_energie_wh = akku.energie_abgeben(3000) + print(f"Abgegebene Energie: {abgegebene_energie_wh} Wh, Ladezustand danach: {akku.ladezustand_in_prozent()}%, Aktueller Energieinhalt: {akku.aktueller_energieinhalt()} Wh") + + akku.energie_laden(6000) + print(f"Ladezustand nach weiterem Laden: {akku.ladezustand_in_prozent()}%, Aktueller Energieinhalt: {akku.aktueller_energieinhalt()} Wh") diff --git a/modules/class_ems.py b/modules/class_ems.py new file mode 100644 index 0000000..fbe365c --- /dev/null +++ b/modules/class_ems.py @@ -0,0 +1,32 @@ +class EnergieManagementSystem: + def __init__(self, akku, lastkurve_wh, pv_prognose_wh): + self.akku = akku + self.lastkurve_wh = lastkurve_wh + self.pv_prognose_wh = pv_prognose_wh + + def simuliere(self): + eigenverbrauch_wh = 0 + netzeinspeisung_wh = 0 + netzbezug_wh = 0 + + for stunde in range(len(self.lastkurve_wh)): + verbrauch = self.lastkurve_wh[stunde] + erzeugung = self.pv_prognose_wh[stunde] + + if erzeugung > verbrauch: + überschuss = erzeugung - verbrauch + eigenverbrauch_wh += verbrauch + geladene_energie = min(überschuss, self.akku.kapazitaet_wh - self.akku.soc_wh) + self.akku.energie_laden(geladene_energie) + netzeinspeisung_wh += überschuss - geladene_energie + else: + eigenverbrauch_wh += erzeugung + benötigte_energie = verbrauch - erzeugung + aus_akku = self.akku.energie_abgeben(benötigte_energie) + netzbezug_wh += benötigte_energie - aus_akku + + return { + 'Eigenverbrauch_Wh': eigenverbrauch_wh, + 'Netzeinspeisung_Wh': netzeinspeisung_wh, + 'Netzbezug_Wh': netzbezug_wh + } diff --git a/modules/class_pv_forecast.py b/modules/class_pv_forecast.py index 3da71e2..e662008 100644 --- a/modules/class_pv_forecast.py +++ b/modules/class_pv_forecast.py @@ -54,6 +54,18 @@ class PVForecast: def get_forecast_data(self): return self.forecast_data + + def get_forecast_for_date(self, input_date_str): + input_date = datetime.strptime(input_date_str, "%Y-%m-%d") + daily_forecast_obj = [data for data in self.forecast_data if datetime.strptime(data.get_date_time(), "%Y-%m-%dT%H:%M:%S.%f%z").date() == input_date.date()] + daily_forecast = [] + for d in daily_forecast_obj: + daily_forecast.append(d.get_ac_power()) + + return np.array(daily_forecast) + + + # Beispiel für die Verwendung der Klasse diff --git a/test.py b/test.py new file mode 100644 index 0000000..ddf98e8 --- /dev/null +++ b/test.py @@ -0,0 +1,84 @@ +from flask import Flask, jsonify, request +import numpy as np +from datetime import datetime +from modules.class_load import * +from modules.class_ems import * +from modules.class_pv_forecast import * +from modules.class_akku import * +from pprint import pprint + + + +date = "2024-02-16" +akku_size = 100 # Wh +year_energy = 200*1000 #Wh + + +akku = PVAkku(akku_size) + +# Load Forecast +lf = LoadForecast(filepath=r'load_profiles.npz', year_energy=year_energy) +specific_date_load = lf.get_daily_stats(date)[0,...] # Datum anpassen + +pprint(specific_date_load.shape) + +# PV Forecast +PVforecast = PVForecast(r'.\test_data\pvprognose.json') +pv_forecast = PVforecast.get_forecast_for_date(date) +pprint(pv_forecast.shape) + + + +ems = EnergieManagementSystem(akku, specific_date_load, pv_forecast) +o = ems.simuliere() +pprint(o) + +# for data in forecast.get_forecast_data(): + # print(data.get_date_time(), data.get_dc_power(), data.get_ac_power(), data.get_windspeed_10m(), data.get_temperature())for data in forecast.get_forecast_data(): + + + + +# app = Flask(__name__) + + + +# @app.route('/getdata', methods=['GET']) +# def get_data(): + # # Hole das Datum aus den Query-Parametern + # date_str = request.args.get('date') + # year_energy = request.args.get('year_energy') + + # try: + # # Konvertiere das Datum in ein datetime-Objekt + # date_obj = datetime.strptime(date_str, '%Y-%m-%d') + # filepath = r'.\load_profiles.npz' # Pfad zur JSON-Datei anpassen + # lf = cl.LoadForecast(filepath=filepath, year_energy=float(year_energy)) + # specific_date_prices = lf.get_daily_stats('2024-02-16') + + + # # Berechne den Tag des Jahres + # #day_of_year = date_obj.timetuple().tm_yday + + # # Konvertiere den Tag des Jahres in einen String, falls die Schlüssel als Strings gespeichert sind + # #day_key = int(day_of_year) + # #print(day_key) + # # Überprüfe, ob der Tag im Jahr in den Daten vorhanden ist + # array_list = lf.get_daily_stats(date_str) + # pprint(array_list) + # pprint(array_list.shape) + # if array_list.shape == (2,24): + # #if day_key < len(load_profiles_exp): + # # Konvertiere das Array in eine Liste für die JSON-Antwort + # #((load_profiles_exp_l[day_key]).tolist(),(load_profiles_std_l)[day_key].tolist()) + + # return jsonify({date_str: array_list.tolist()}) + # else: + # return jsonify({"error": "Datum nicht gefunden"}), 404 + # except ValueError: + # # Wenn das Datum nicht im richtigen Format ist oder ungültig ist + # return jsonify({"error": "Ungültiges Datum"}), 400 + +# if __name__ == '__main__': + # app.run(debug=True) +