mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-04-19 08:55:15 +00:00
E-Auto integriert und visualisiert
This commit is contained in:
parent
9e20df9edc
commit
356abf1b08
122
modules/class_eauto.py
Normal file
122
modules/class_eauto.py
Normal file
@ -0,0 +1,122 @@
|
|||||||
|
import json
|
||||||
|
from datetime import datetime, timedelta, timezone
|
||||||
|
import numpy as np
|
||||||
|
from pprint import pprint
|
||||||
|
|
||||||
|
class EAuto:
|
||||||
|
def __init__(self, soc=None, capacity = None, power_charge = None, load_allowed = None):
|
||||||
|
self.soc = soc
|
||||||
|
self.akku_kapazitaet = capacity
|
||||||
|
self.ladegeschwindigkeit = power_charge
|
||||||
|
self.laden_moeglich = None
|
||||||
|
self.stuendlicher_soc = []
|
||||||
|
self.stuendliche_last = [] # Hinzugefügt für die Speicherung der stündlichen Last
|
||||||
|
self.laden_moeglich = load_allowed
|
||||||
|
self.berechne_ladevorgang()
|
||||||
|
|
||||||
|
def set_laden_moeglich(self, laden_moeglich):
|
||||||
|
self.laden_moeglich = laden_moeglich
|
||||||
|
self.stuendlicher_soc = [self.soc] # Beginnt mit dem aktuellen SoC
|
||||||
|
self.stuendliche_last = [] # Zurücksetzen der stündlichen Last
|
||||||
|
|
||||||
|
def berechne_ladevorgang(self):
|
||||||
|
if self.laden_moeglich is None:
|
||||||
|
print("Lademöglichkeit wurde nicht gesetzt.")
|
||||||
|
return
|
||||||
|
|
||||||
|
for moeglich in self.laden_moeglich:
|
||||||
|
if moeglich == 1 and self.soc < 100:
|
||||||
|
geladene_energie = min(self.ladegeschwindigkeit, (100 - self.soc) / 100 * self.akku_kapazitaet)
|
||||||
|
self.soc += geladene_energie / self.akku_kapazitaet * 100
|
||||||
|
self.soc = min(100, self.soc)
|
||||||
|
self.stuendliche_last.append(geladene_energie)
|
||||||
|
else:
|
||||||
|
self.stuendliche_last.append(0) # Keine Ladung in dieser Stunde
|
||||||
|
self.stuendlicher_soc.append(self.soc)
|
||||||
|
|
||||||
|
# Umwandlung der stündlichen Last in ein NumPy-Array
|
||||||
|
self.stuendliche_last = np.array(self.stuendliche_last)
|
||||||
|
|
||||||
|
def get_stuendliche_last(self):
|
||||||
|
"""Gibt das NumPy-Array mit der stündlichen Last zurück."""
|
||||||
|
return self.stuendliche_last
|
||||||
|
|
||||||
|
def get_stuendlicher_soc(self):
|
||||||
|
"""Gibt den stündlichen SoC als Liste zurück."""
|
||||||
|
return self.stuendlicher_soc
|
||||||
|
|
||||||
|
|
||||||
|
# class EAuto:
|
||||||
|
# def __init__(self, soc, akku_kapazitaet, ladegeschwindigkeit):
|
||||||
|
# self.soc = soc
|
||||||
|
# self.akku_kapazitaet = akku_kapazitaet
|
||||||
|
# self.ladegeschwindigkeit = ladegeschwindigkeit
|
||||||
|
# self.laden_moeglich = None
|
||||||
|
# # Initialisieren des Arrays für den stündlichen SoC
|
||||||
|
# self.stuendlicher_soc = []
|
||||||
|
|
||||||
|
# def set_laden_moeglich(self, laden_moeglich):
|
||||||
|
# """
|
||||||
|
# Setzt das Array, das angibt, wann das Laden möglich ist.
|
||||||
|
# :param laden_moeglich: Ein Array von 0 und 1, das die Lademöglichkeit angibt
|
||||||
|
# """
|
||||||
|
# self.laden_moeglich = laden_moeglich
|
||||||
|
# # Zurücksetzen des stündlichen SoC Arrays bei jeder neuen Lademöglichkeit
|
||||||
|
# self.stuendlicher_soc = [self.soc] # Start-SoC hinzufügen
|
||||||
|
|
||||||
|
# def berechne_ladevorgang(self):
|
||||||
|
# """
|
||||||
|
# Berechnet den Ladevorgang basierend auf der Ladegeschwindigkeit und der Lademöglichkeit.
|
||||||
|
# Aktualisiert den SoC entsprechend und speichert den stündlichen SoC.
|
||||||
|
# """
|
||||||
|
# if self.laden_moeglich is None:
|
||||||
|
# print("Lademöglichkeit wurde nicht gesetzt.")
|
||||||
|
# return
|
||||||
|
|
||||||
|
# for i, moeglich in enumerate(self.laden_moeglich):
|
||||||
|
# if moeglich == 1:
|
||||||
|
# # Berechnen, wie viel Energie in einer Stunde geladen werden kann
|
||||||
|
# geladene_energie = min(self.ladegeschwindigkeit, (100 - self.soc) / 100 * self.akku_kapazitaet)
|
||||||
|
# # Aktualisieren des SoC
|
||||||
|
# self.soc += geladene_energie / self.akku_kapazitaet * 100
|
||||||
|
# # Sicherstellen, dass der SoC nicht über 100% geht
|
||||||
|
# self.soc = min(100, self.soc)
|
||||||
|
# print(f"Stunde {i}: Geladen {geladene_energie} kWh, neuer SoC: {self.soc}%")
|
||||||
|
# else:
|
||||||
|
# # Wenn nicht geladen wird, bleibt der SoC gleich
|
||||||
|
# print(f"Stunde {i}: Nicht geladen, SoC bleibt bei {self.soc}%")
|
||||||
|
# self.stuendlicher_soc.append(self.soc) # Aktuellen SoC zum Array hinzufügen
|
||||||
|
# if self.soc >= 100:
|
||||||
|
# print("Akku vollständig geladen.")
|
||||||
|
# break
|
||||||
|
|
||||||
|
# def berechne_benoetigte_energie(self):
|
||||||
|
# """
|
||||||
|
# Berechnet die Gesamtenergie, die benötigt wird, um den Akku vollständig zu laden.
|
||||||
|
# """
|
||||||
|
# return (100 - self.soc) / 100 * self.akku_kapazitaet
|
||||||
|
|
||||||
|
# def get_stuendlicher_soc(self):
|
||||||
|
# """
|
||||||
|
# Gibt den stündlichen Ladezustand (SoC) als Array zurück.
|
||||||
|
# """
|
||||||
|
# return self.stuendlicher_soc
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# Initialisierung des Elektroauto-Ladens
|
||||||
|
mein_eauto = EAuto(soc=50, akku_kapazitaet=60, ladegeschwindigkeit=11)
|
||||||
|
|
||||||
|
# Festlegen, wann das Laden möglich ist (1 = Laden erlaubt, 0 = Laden nicht erlaubt)
|
||||||
|
# Beispiel: Laden ist nur während der Nachtstunden und frühen Morgenstunden erlaubt
|
||||||
|
laden_moeglich = [0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1]
|
||||||
|
mein_eauto.set_laden_moeglich(laden_moeglich)
|
||||||
|
|
||||||
|
# Durchführen des Ladevorgangs
|
||||||
|
mein_eauto.berechne_ladevorgang()
|
||||||
|
|
||||||
|
# Abrufen und Ausgeben des stündlichen Ladezustands
|
||||||
|
stuendlicher_soc = mein_eauto.get_stuendlicher_soc()
|
||||||
|
print("\nStündlicher SoC während des Ladevorgangs:")
|
||||||
|
for stunde, soc in enumerate(stuendlicher_soc):
|
||||||
|
print(f"Stunde {stunde}: SoC = {soc}%")
|
@ -1,6 +1,5 @@
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
from modules.class_generic_load import *
|
|
||||||
|
|
||||||
|
|
||||||
class EnergieManagementSystem:
|
class EnergieManagementSystem:
|
||||||
|
@ -6,11 +6,12 @@ from datetime import datetime
|
|||||||
import hashlib, requests
|
import hashlib, requests
|
||||||
|
|
||||||
class HourlyElectricityPriceForecast:
|
class HourlyElectricityPriceForecast:
|
||||||
def __init__(self, source, cache_dir='cache'):
|
def __init__(self, source, cache_dir='cache', abgaben=0.00019):
|
||||||
self.cache_dir = cache_dir
|
self.cache_dir = cache_dir
|
||||||
if not os.path.exists(self.cache_dir):
|
if not os.path.exists(self.cache_dir):
|
||||||
os.makedirs(self.cache_dir)
|
os.makedirs(self.cache_dir)
|
||||||
self.prices = self.load_data(source)
|
self.prices = self.load_data(source)
|
||||||
|
self.abgaben = abgaben
|
||||||
|
|
||||||
def load_data(self, source):
|
def load_data(self, source):
|
||||||
if source.startswith('http'):
|
if source.startswith('http'):
|
||||||
@ -42,8 +43,8 @@ class HourlyElectricityPriceForecast:
|
|||||||
|
|
||||||
def get_price_for_date(self, date_str):
|
def get_price_for_date(self, date_str):
|
||||||
"""Gibt alle Preise für das spezifizierte Datum zurück."""
|
"""Gibt alle Preise für das spezifizierte Datum zurück."""
|
||||||
date_prices = [entry["marketpriceEurocentPerKWh"] for entry in self.prices if date_str in entry['end']]
|
date_prices = [entry["marketpriceEurocentPerKWh"]+self.abgaben for entry in self.prices if date_str in entry['end']]
|
||||||
return np.array(date_prices)/(1000.0*100.0)
|
return np.array(date_prices)/(1000.0*100.0) + self.abgaben
|
||||||
|
|
||||||
def get_price_for_daterange(self, start_date_str, end_date_str):
|
def get_price_for_daterange(self, start_date_str, end_date_str):
|
||||||
"""Gibt alle Preise zwischen dem Start- und Enddatum zurück."""
|
"""Gibt alle Preise zwischen dem Start- und Enddatum zurück."""
|
||||||
@ -61,107 +62,3 @@ class HourlyElectricityPriceForecast:
|
|||||||
|
|
||||||
return np.array(price_list)
|
return np.array(price_list)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# def get_price_for_hour(self, datetime_str):
|
|
||||||
# """Gibt den Preis für die spezifizierte Stunde zurück."""
|
|
||||||
# hour_price = [entry for entry in self.prices if datetime_str in entry['start']]
|
|
||||||
# return hour_price[0] if hour_price else None
|
|
||||||
|
|
||||||
# # Beispiel zur Verwendung der Klasse
|
|
||||||
# filepath = '/mnt/data/strompreise_akkudokAPI.json' # Pfad zur JSON-Datei
|
|
||||||
# strompreise = Strompreise(filepath)
|
|
||||||
|
|
||||||
# # Preise für ein spezifisches Datum erhalten
|
|
||||||
# date_str = '2024-02-25'
|
|
||||||
# prices_for_date = strompreise.get_price_for_date(date_str)
|
|
||||||
# print(f"Preise für {date_str}: {prices_for_date}")
|
|
||||||
|
|
||||||
# # Preis für eine spezifische Stunde erhalten
|
|
||||||
# datetime_str = '2024-02-25T15:00:00.000Z'
|
|
||||||
# price_for_hour = strompreise.get_price_for_hour(datetime_str)
|
|
||||||
# print(f"Preis für {datetime_str}: {price_for_hour}")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# class HourlyElectricityPriceForecast:
|
|
||||||
# class PriceData:
|
|
||||||
# def __init__(self, total, energy, tax, starts_at, currency, level):
|
|
||||||
# self.total = total/1000.0
|
|
||||||
# self.energy = energy/1000.0
|
|
||||||
# self.tax = tax/1000.0
|
|
||||||
# self.starts_at = datetime.strptime(starts_at, '%Y-%m-%dT%H:%M:%S.%f%z')
|
|
||||||
|
|
||||||
# self.currency = currency
|
|
||||||
# self.level = level
|
|
||||||
|
|
||||||
# # Getter-Methoden
|
|
||||||
# def get_total(self):
|
|
||||||
# return self.total
|
|
||||||
|
|
||||||
# def get_energy(self):
|
|
||||||
# return self.energy
|
|
||||||
|
|
||||||
# def get_tax(self):
|
|
||||||
# return self.tax
|
|
||||||
|
|
||||||
# def get_starts_at(self):
|
|
||||||
# return self.starts_at
|
|
||||||
|
|
||||||
# def get_currency(self):
|
|
||||||
# return self.currency
|
|
||||||
|
|
||||||
# def get_level(self):
|
|
||||||
# return self.level
|
|
||||||
|
|
||||||
# def __init__(self, filepath):
|
|
||||||
# self.filepath = filepath
|
|
||||||
# self.price_data = []
|
|
||||||
# self.load_data()
|
|
||||||
|
|
||||||
# def get_prices_for_date(self, query_date):
|
|
||||||
# query_date = datetime.strptime(query_date, '%Y-%m-%d').date()
|
|
||||||
# prices_for_date = [price.get_total() for price in self.price_data if price.starts_at.date() == query_date]
|
|
||||||
|
|
||||||
# return np.array(prices_for_date)
|
|
||||||
|
|
||||||
# def get_price_for_datetime(self, query_datetime):
|
|
||||||
# query_datetime = datetime.strptime(query_datetime, '%Y-%m-%d %H').replace(minute=0, second=0, microsecond=0)
|
|
||||||
# query_datetime = query_datetime.replace(tzinfo=timezone(timedelta(hours=1)))
|
|
||||||
|
|
||||||
# for price in self.price_data:
|
|
||||||
# #print(price.starts_at.replace(minute=0, second=0, microsecond=0) , " ", query_datetime, " == ",price.starts_at.replace(minute=0, second=0, microsecond=0) == query_datetime)
|
|
||||||
# if price.starts_at.replace(minute=0, second=0, microsecond=0) == query_datetime:
|
|
||||||
# return np.array(price)
|
|
||||||
# return None
|
|
||||||
|
|
||||||
|
|
||||||
# def load_data(self):
|
|
||||||
# with open(self.filepath, 'r') as file:
|
|
||||||
# data = json.load(file)
|
|
||||||
# for item in data['payload']:
|
|
||||||
# self.price_data.append(self.PriceData(
|
|
||||||
# total=item['total'],
|
|
||||||
# energy=item['energy'],
|
|
||||||
# tax=item['tax'],
|
|
||||||
# starts_at=item['startsAt'],
|
|
||||||
# currency=item['currency'],
|
|
||||||
# level=item['level']
|
|
||||||
# ))
|
|
||||||
|
|
||||||
# def get_price_data(self):
|
|
||||||
# return self.price_data
|
|
||||||
|
|
||||||
# # Beispiel für die Verwendung der Klasse
|
|
||||||
# if __name__ == '__main__':
|
|
||||||
# filepath = r'..\test_data\strompreis.json' # Pfad zur JSON-Datei anpassen
|
|
||||||
# price_forecast = HourlyElectricityPriceForecast(filepath)
|
|
||||||
# specific_date_prices = price_forecast.get_prices_for_date('2024-02-16') # Datum anpassen
|
|
||||||
|
|
||||||
# specific_date_prices = price_forecast.get_price_for_datetime('2024-02-16 12')
|
|
||||||
# print(specific_date_prices)
|
|
||||||
# #for price in price_forecast.get_price_data():
|
|
||||||
# # print(price.get_starts_at(), price.get_total(), price.get_currency())
|
|
||||||
|
@ -1,26 +1,35 @@
|
|||||||
import numpy as np
|
import numpy as np
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
|
import numpy as np
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from modules.class_load_container import Gesamtlast # Stellen Sie sicher, dass dies dem tatsächlichen Importpfad entspricht
|
||||||
|
|
||||||
|
|
||||||
def visualisiere_ergebnisse(last,leistung_haushalt,leistung_wp, pv_forecast, strompreise, ergebnisse):
|
|
||||||
|
|
||||||
#print(last)
|
|
||||||
|
|
||||||
|
|
||||||
stunden = np.arange(1, len(last)+1) # 1 bis 24 Stunden
|
def visualisiere_ergebnisse(gesamtlast,leistung_haushalt,leistung_wp, pv_forecast, strompreise, ergebnisse):
|
||||||
|
|
||||||
|
|
||||||
# Last und PV-Erzeugung
|
# Last und PV-Erzeugung
|
||||||
plt.figure(figsize=(14, 10))
|
plt.figure(figsize=(14, 10))
|
||||||
|
|
||||||
plt.subplot(3, 1, 1)
|
plt.subplot(3, 1, 1)
|
||||||
plt.plot(stunden, last, label='Last (Wh)', marker='o')
|
stunden = np.arange(1, len(next(iter(gesamtlast.lasten.values()))) + 1)
|
||||||
plt.plot(stunden, leistung_haushalt, label='leistung_haushalt (Wh)', marker='o')
|
|
||||||
plt.plot(stunden, leistung_wp, label='leistung_wp (Wh)', marker='o')
|
|
||||||
plt.plot(stunden, pv_forecast, label='PV-Erzeugung (Wh)', marker='x')
|
# Einzellasten plotten
|
||||||
plt.title('Last und PV-Erzeugung')
|
for name, last_array in gesamtlast.lasten.items():
|
||||||
plt.xlabel('Stunde des Tages')
|
plt.plot(stunden, last_array, label=f'{name} (Wh)', marker='o')
|
||||||
plt.ylabel('Energie (Wh)')
|
|
||||||
plt.legend()
|
# Gesamtlast berechnen und plotten
|
||||||
|
gesamtlast_array = gesamtlast.gesamtlast_berechnen()
|
||||||
|
plt.plot(stunden, gesamtlast_array, label='Gesamtlast (Wh)', marker='o', linewidth=2, linestyle='--')
|
||||||
|
|
||||||
|
plt.xlabel('Stunde')
|
||||||
|
plt.ylabel('Last (Wh)')
|
||||||
|
plt.title('Lastprofile')
|
||||||
plt.grid(True)
|
plt.grid(True)
|
||||||
|
plt.legend()
|
||||||
|
|
||||||
# Strompreise
|
# Strompreise
|
||||||
stundenp = np.arange(1, len(strompreise)+1)
|
stundenp = np.arange(1, len(strompreise)+1)
|
||||||
|
31
test.py
31
test.py
@ -7,8 +7,9 @@ from modules.class_pv_forecast import *
|
|||||||
from modules.class_akku import *
|
from modules.class_akku import *
|
||||||
from modules.class_strompreis import *
|
from modules.class_strompreis import *
|
||||||
from modules.class_heatpump import *
|
from modules.class_heatpump import *
|
||||||
from modules.class_generic_load import *
|
|
||||||
from modules.class_load_container import *
|
from modules.class_load_container import *
|
||||||
|
from modules.class_eauto import *
|
||||||
|
|
||||||
from pprint import pprint
|
from pprint import pprint
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from modules.visualize import *
|
from modules.visualize import *
|
||||||
@ -33,6 +34,13 @@ wp = Waermepumpe(max_heizleistung,prediction_hours)
|
|||||||
akku = PVAkku(akku_size,prediction_hours)
|
akku = PVAkku(akku_size,prediction_hours)
|
||||||
discharge_array = np.full(prediction_hours,1)
|
discharge_array = np.full(prediction_hours,1)
|
||||||
|
|
||||||
|
laden_moeglich = np.full(prediction_hours,1)
|
||||||
|
eauto = EAuto(soc=60, capacity = 60000, power_charge = 7000, load_allowed = laden_moeglich)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#Gesamtlast
|
#Gesamtlast
|
||||||
#############
|
#############
|
||||||
@ -46,12 +54,6 @@ lf = LoadForecast(filepath=r'load_profiles.npz', year_energy=year_energy)
|
|||||||
leistung_haushalt = lf.get_stats_for_date_range(date_now,date)[0,...].flatten()
|
leistung_haushalt = lf.get_stats_for_date_range(date_now,date)[0,...].flatten()
|
||||||
gesamtlast.hinzufuegen("Haushalt", leistung_haushalt)
|
gesamtlast.hinzufuegen("Haushalt", leistung_haushalt)
|
||||||
|
|
||||||
# Generic Load
|
|
||||||
##############
|
|
||||||
# zusatzlast1 = generic_load()
|
|
||||||
# zusatzlast1.setze_last(24+12, 0.5, 2000) # Startet um 1 Uhr, dauert 0.5 Stunden, mit 2 kW
|
|
||||||
|
|
||||||
|
|
||||||
# PV Forecast
|
# PV Forecast
|
||||||
###############
|
###############
|
||||||
#PVforecast = PVForecast(filepath=os.path.join(r'test_data', r'pvprognose.json'))
|
#PVforecast = PVForecast(filepath=os.path.join(r'test_data', r'pvprognose.json'))
|
||||||
@ -73,21 +75,26 @@ specific_date_prices = price_forecast.get_price_for_daterange(date_now,date)
|
|||||||
leistung_wp = wp.simulate_24h(temperature_forecast)
|
leistung_wp = wp.simulate_24h(temperature_forecast)
|
||||||
gesamtlast.hinzufuegen("Heatpump", leistung_wp)
|
gesamtlast.hinzufuegen("Heatpump", leistung_wp)
|
||||||
|
|
||||||
# print(gesamtlast.gesamtlast_berechnen())
|
|
||||||
# sys.exit()
|
# EAuto
|
||||||
|
######################
|
||||||
|
leistung_eauto = eauto.get_stuendliche_last()
|
||||||
|
gesamtlast.hinzufuegen("eauto", leistung_eauto)
|
||||||
|
|
||||||
|
print(gesamtlast.gesamtlast_berechnen())
|
||||||
|
|
||||||
# EMS / Stromzähler Bilanz
|
# EMS / Stromzähler Bilanz
|
||||||
ems = EnergieManagementSystem(akku, gesamtlast.gesamtlast_berechnen(), pv_forecast, specific_date_prices, einspeiseverguetung_cent_pro_wh)
|
ems = EnergieManagementSystem(akku, gesamtlast.gesamtlast_berechnen(), pv_forecast, specific_date_prices, einspeiseverguetung_cent_pro_wh)
|
||||||
|
|
||||||
|
|
||||||
o = ems.simuliere_ab_jetzt()
|
o = ems.simuliere(0)#ems.simuliere_ab_jetzt()
|
||||||
pprint(o)
|
pprint(o)
|
||||||
pprint(o["Gesamtbilanz_Euro"])
|
pprint(o["Gesamtbilanz_Euro"])
|
||||||
|
|
||||||
visualisiere_ergebnisse(gesamtlast.gesamtlast_berechnen(),leistung_haushalt,leistung_wp, pv_forecast, specific_date_prices, o)
|
visualisiere_ergebnisse(gesamtlast,leistung_haushalt,leistung_wp, pv_forecast, specific_date_prices, o)
|
||||||
|
|
||||||
|
|
||||||
sys.exit()
|
#sys.exit()
|
||||||
|
|
||||||
# Optimierung
|
# Optimierung
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user