Strompreis entkoppelt, kann jetzt als Array übergeben werden.

This commit is contained in:
Bla Bla 2024-07-30 09:22:55 +02:00
parent 95b0ec5664
commit 4cff8fb8a6
7 changed files with 314 additions and 156 deletions

View File

@ -8,6 +8,7 @@ from modules.class_strompreis import *
from modules.class_heatpump import * from modules.class_heatpump import *
from modules.class_load_container import * from modules.class_load_container import *
from modules.class_sommerzeit import * from modules.class_sommerzeit import *
from modules.class_soc_calc import *
from modules.visualize import * from modules.visualize import *
from modules.class_battery_soc_predictor import * from modules.class_battery_soc_predictor import *
import os import os
@ -23,38 +24,56 @@ from modules.class_optimize import *
import numpy as np import numpy as np
import random import random
import os import os
from config import *
app = Flask(__name__) app = Flask(__name__)
opt_class = optimization_problem(prediction_hours=48, strafe=10) opt_class = optimization_problem(prediction_hours=48, strafe=10)
soc_predictor = BatterySocPredictor.load_model('battery_model.pkl')
@app.route('/soc', methods=['GET']) @app.route('/soc', methods=['GET'])
def flask_soc(): def flask_soc():
if request.method == 'GET':
# URL-Parameter lesen
voltage = request.args.get('voltage')
current = request.args.get('current')
# Erforderliche Parameter prüfen
if voltage is None or current is None:
missing_params = []
if voltage is None:
missing_params.append('voltage')
if current is None:
missing_params.append('current')
return jsonify({"error": f"Fehlende Parameter: {', '.join(missing_params)}"}), 400
# Werte in ein numpy Array umwandeln # MariaDB Verbindungsdetails
x = np.array( [[float(voltage), float(current)]] ) config = db_config
# Parameter festlegen
voltage_high_threshold = 55.4 # 100% SoC
voltage_low_threshold = 46.5 # 0% SoC
current_low_threshold = 2 # Niedriger Strom für beide Zustände
gap = 30 # Zeitlücke in Minuten zum Gruppieren von Maxima/Minima
bat_capacity = 33 * 1000 / 48
# Zeitpunkt X definieren
zeitpunkt_x = (datetime.now() - timedelta(weeks=3)).strftime('%Y-%m-%d %H:%M:%S')
# BatteryDataProcessor instanziieren und verwenden
processor = BatteryDataProcessor(config, voltage_high_threshold, voltage_low_threshold, current_low_threshold, gap,bat_capacity)
processor.connect_db()
processor.fetch_data(zeitpunkt_x)
processor.process_data()
last_points_100_df, last_points_0_df = processor.find_soc_points()
soc_df, integration_results = processor.calculate_resetting_soc(last_points_100_df, last_points_0_df)
#soh_df = processor.calculate_soh(integration_results)
processor.update_database_with_soc(soc_df)
#processor.plot_data(last_points_100_df, last_points_0_df, soc_df)
processor.disconnect_db()
# Simulation durchführen return jsonify("Done")
ergebnis = soc_predictor.predict(x)
print(ergebnis)
@app.route('/strompreis', methods=['GET'])
return jsonify(ergebnis) def flask_strompreis():
date_now,date = get_start_enddate(prediction_hours,startdate=datetime.now().date())
filepath = os.path.join (r'test_data', r'strompreise_akkudokAPI.json') # Pfad zur JSON-Datei anpassen
#price_forecast = HourlyElectricityPriceForecast(source=filepath)
price_forecast = HourlyElectricityPriceForecast(source="https://api.akkudoktor.net/prices?start="+date_now+"&end="+date+"", prediction_hours=prediction_hours)
specific_date_prices = price_forecast.get_price_for_daterange(date_now,date)
#print(specific_date_prices)
return jsonify(specific_date_prices.tolist())
@app.route('/optimize', methods=['POST']) @app.route('/optimize', methods=['POST'])
@ -63,7 +82,7 @@ def flask_optimize():
parameter = request.json parameter = request.json
# Erforderliche Parameter prüfen # Erforderliche Parameter prüfen
erforderliche_parameter = [ 'pv_akku_cap', 'year_energy',"einspeiseverguetung_euro_pro_wh", 'max_heizleistung', 'pv_forecast_url', 'eauto_min_soc', "eauto_cap","eauto_charge_efficiency","eauto_charge_power","eauto_soc","pv_soc","start_solution","pvpowernow","haushaltsgeraet_dauer","haushaltsgeraet_wh"] erforderliche_parameter = [ 'strompreis_euro_pro_wh','pv_akku_cap', 'year_energy',"einspeiseverguetung_euro_pro_wh", 'max_heizleistung', 'pv_forecast_url', 'eauto_min_soc', "eauto_cap","eauto_charge_efficiency","eauto_charge_power","eauto_soc","pv_soc","start_solution","pvpowernow","haushaltsgeraet_dauer","haushaltsgeraet_wh"]
for p in erforderliche_parameter: for p in erforderliche_parameter:
if p not in parameter: if p not in parameter:
return jsonify({"error": f"Fehlender Parameter: {p}"}), 400 return jsonify({"error": f"Fehlender Parameter: {p}"}), 400

View File

@ -1,6 +1,6 @@
import numpy as np import numpy as np
class PVAkku: class PVAkku:
def __init__(self, kapazitaet_wh=None, hours=None, lade_effizienz=0.8, entlade_effizienz=1.0,max_ladeleistung_w=None,start_soc_prozent=0,min_soc_prozent=0,max_soc_prozent=100): def __init__(self, kapazitaet_wh=None, hours=None, lade_effizienz=0.88, entlade_effizienz=0.88,max_ladeleistung_w=None,start_soc_prozent=0,min_soc_prozent=0,max_soc_prozent=100):
# Kapazität des Akkus in Wh # Kapazität des Akkus in Wh
self.kapazitaet_wh = kapazitaet_wh self.kapazitaet_wh = kapazitaet_wh
# Initialer Ladezustand des Akkus in Wh # Initialer Ladezustand des Akkus in Wh

View File

@ -1,20 +1,37 @@
import numpy as np import numpy as np
import pandas as pd import pandas as pd
import joblib import joblib, json
from sklearn.preprocessing import StandardScaler from sklearn.preprocessing import StandardScaler
from sklearn.gaussian_process import GaussianProcessRegressor from sklearn.gaussian_process import GaussianProcessRegressor
from sklearn.gaussian_process.kernels import RBF, ConstantKernel, WhiteKernel from sklearn.gaussian_process.kernels import RBF, ConstantKernel, WhiteKernel, Matern,DotProduct
from sklearn.model_selection import train_test_split from sklearn.model_selection import train_test_split
from tensorflow.keras.models import Sequential, load_model
from tensorflow.keras.layers import LSTM, Dense,Dropout
from sklearn.preprocessing import MinMaxScaler
import matplotlib.pyplot as plt
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.regularizers import l1, l2, l1_l2
from scipy.signal import savgol_filter
import numpy as np import numpy as np
import matplotlib.pyplot as plt import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense, Dropout, RepeatVector, TimeDistributed
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.optimizers import Adam
from tensorflow.keras.regularizers import l2
import matplotlib.pyplot as plt
from sklearn.metrics import mean_absolute_error, mean_squared_error
class BatterySocPredictor:
class BatterySocPredictorGauss:
def __init__(self): def __init__(self):
# Initialisierung von Scaler und Gaußschem Prozessmodell # Initialisierung von Scaler und Gaußschem Prozessmodell
self.scaler = StandardScaler() self.scaler = StandardScaler()
kernel = WhiteKernel(1.0, (1e-7, 1e3)) + RBF(length_scale=(0.1,0.1), length_scale_bounds=((1e-7, 1e3),(1e-7, 1e3))) kernel = WhiteKernel(1.0, (1e-7, 1e3)) + Matern(length_scale=(0.1,0.1,0.1), length_scale_bounds=((1e-7, 1e3),(1e-7, 1e3),(1e-7, 1e3))) + DotProduct()
self.gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10, alpha=1e-2, normalize_y=True) self.gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10, alpha=1e-3, normalize_y=True)
def fit(self, X, y): def fit(self, X, y):
# Transformiere die Zielvariable # Transformiere die Zielvariable
@ -34,7 +51,7 @@ class BatterySocPredictor:
# Rücktransformieren der Unsicherheiten # Rücktransformieren der Unsicherheiten
sigmoid_y_pred = 1 / (1 + np.exp(-y_pred_transformed)) sigmoid_y_pred = 1 / (1 + np.exp(-y_pred_transformed))
sigma = sigma_transformed * 101 * sigmoid_y_pred * (1 - sigmoid_y_pred) sigma = sigma_transformed * 101 * sigmoid_y_pred * (1 - sigmoid_y_pred)
return float(y_pred), float(sigma) return y_pred
def save_model(self, file_path): def save_model(self, file_path):
# Speichere das gesamte Modell-Objekt # Speichere das gesamte Modell-Objekt
@ -44,132 +61,243 @@ class BatterySocPredictor:
def load_model(file_path): def load_model(file_path):
# Lade das Modell-Objekt # Lade das Modell-Objekt
return joblib.load(file_path) return joblib.load(file_path)
class BatterySoCPredictorLSTM:
def __init__(self, model_path=None, scaler_path=None, gauss=None):
self.scaler = MinMaxScaler(feature_range=(0, 1))
self.target_scaler = MinMaxScaler(feature_range=(0, 1))
self.seq_length = 5 # Anzahl der Zeitschritte in der Eingabesequenz
self.n_future_steps = 1 # Anzahl der zukünftigen Schritte, die vorhergesagt werden sollen
self.gauss_model = BatterySocPredictorGauss.load_model(gauss)
if model_path:
self.model = load_model(model_path)
else:
self.model = self._build_model()
if scaler_path:
self.load_scalers(scaler_path)
def _build_model(self):
regu = 0.00 # Regularisierungsrate
model = Sequential()
model.add(LSTM(20, activation='relu', return_sequences=True, input_shape=(self.seq_length, 4), kernel_regularizer=l2(regu)))
model.add(LSTM(20, activation='relu', return_sequences=False, kernel_regularizer=l2(regu)))
model.add(RepeatVector(self.n_future_steps))
model.add(LSTM(20, activation='relu', return_sequences=True, kernel_regularizer=l2(regu)))
model.add(TimeDistributed(Dense(1, kernel_regularizer=l2(regu)))) # TimeDistributed Layer für Multi-Step Output
optimizer = Adam(learning_rate=0.0005)
model.compile(optimizer=optimizer, loss='mae')
return model
def fit(self, data_path, epochs=100, batch_size=50, validation_split=0.1):
data = pd.read_csv(data_path)
data['Time'] = pd.to_datetime(data['Time'], unit='ms')
data.set_index('Time', inplace=True)
data.dropna(inplace=True)
# Gauss
#data["temperature_mean"] = data[["data","data.1"]].mean(axis=1)
#data[['battery_voltage', 'battery_current', 'data']]
data["battery_soc_gauss"] = self.gauss_model.predict(data[['battery_voltage', 'battery_current', 'data']].values)
# print(data)
# sys.exit()
scaled_data = self.scaler.fit_transform(data[['battery_voltage', 'battery_current', 'data', 'battery_soc_gauss']].values)
data['scaled_soc'] = self.target_scaler.fit_transform(data[['battery_soc']])
X, y = self._create_sequences(scaled_data, self.seq_length, self.n_future_steps)
print(y.shape)
self.model.fit(X, y, epochs=epochs, batch_size=batch_size, validation_split=validation_split)
def _create_sequences(self, data, seq_length, n_future_steps):
xs, ys = [], []
for i in range(len(data) - seq_length - n_future_steps):
x = data[i:(i + seq_length)]
y = data[(i + seq_length):(i + seq_length + n_future_steps), -1] # Multi-Step Output
xs.append(x)
ys.append(y)
return np.array(xs), np.array(ys)
# def predict(self, test_data_path):
# test_data = pd.read_csv(test_data_path)
# test_data['Time'] = pd.to_datetime(test_data['Time'], unit='ms')
# test_data.set_index('Time', inplace=True)
# test_data.replace('undefined', np.nan, inplace=True)
# test_data.dropna(inplace=True)
# test_data['battery_voltage'] = pd.to_numeric(test_data['battery_voltage'], errors='coerce')
# test_data['battery_current'] = pd.to_numeric(test_data['battery_current'], errors='coerce')
# test_data['battery_soc'] = pd.to_numeric(test_data['battery_soc'], errors='coerce')
# test_data['data.1'] = pd.to_numeric(test_data['data.1'], errors='coerce')
# test_data.dropna(inplace=True)
# scaled_test_data = self.scaler.transform(test_data[['battery_voltage', 'battery_current', 'data.1', 'battery_soc']])
# test_data['scaled_soc'] = self.target_scaler.transform(test_data[['battery_soc']])
# test_data.dropna(inplace=True)
# X_test, _ = self._create_sequences(scaled_test_data, self.seq_length, self.n_future_steps)
# predictions = self.model.predict(X_test)
# predictions = self.target_scaler.inverse_transform(predictions.reshape(-1, 1)).reshape(-1, self.n_future_steps)
# return predictions
def predict_single(self, voltage_current_temp_soc_sequence):
if len(voltage_current_temp_soc_sequence) != self.seq_length or len(voltage_current_temp_soc_sequence[0]) != 3:
raise ValueError("Die Eingabesequenz muss die Form (seq_length, 3) haben.")
soc_gauss = self.gauss_model.predict(voltage_current_temp_soc_sequence)
soc_gauss = soc_gauss.reshape(-1,1)
#print(voltage_current_temp_soc_sequence.shape)
#print(soc_gauss.shape)
voltage_current_sequence = np.hstack([voltage_current_temp_soc_sequence, soc_gauss])
#print(voltage_current_sequence.shape)
print(voltage_current_sequence)
scaled_sequence = self.scaler.transform(voltage_current_sequence)
X = np.array([scaled_sequence])
prediction = self.model.predict(X)
prediction = self.target_scaler.inverse_transform(prediction.reshape(-1, 1)).reshape(-1, self.n_future_steps)
return prediction # Return the sequence of future SoC predictions
def save_model(self, model_path=None, scaler_path=None):
self.model.save(model_path)
scaler_params = {
'scaler_min_': self.scaler.min_.tolist(),
'scaler_scale_': self.scaler.scale_.tolist(),
'target_scaler_min_': self.target_scaler.min_.tolist(),
'target_scaler_scale_': self.target_scaler.scale_.tolist()
}
with open(scaler_path, 'w') as f:
json.dump(scaler_params, f)
def load_scalers(self, scaler_path):
with open(scaler_path, 'r') as f:
scaler_params = json.load(f)
self.scaler.min_ = np.array(scaler_params['scaler_min_'])
self.scaler.scale_ = np.array(scaler_params['scaler_scale_'])
self.target_scaler.min_ = np.array(scaler_params['target_scaler_min_'])
self.target_scaler.scale_ = np.array(scaler_params['target_scaler_scale_'])
if __name__ == '__main__':
train_data_path = 'lstm_train/raw_data_clean.csv'
test_data_path = 'Test_Data.csv'
model_path = 'battery_soc_predictor_lstm_model.keras'
scaler_path = 'battery_soc_predictor_scaler_model'
# # Daten laden und Modell verwenden ####################
# data_path = 'train.csv' # GAUSS + K-Means
# data = pd.read_csv(data_path) ####################
# X = data[['battery_voltage', 'battery_current']] # Daten laden und vorbereiten
# y = data['battery_soc'] data_path = 'k_means.csv'
data = pd.read_csv(data_path, decimal='.')
data.dropna(inplace=True) # Entfernen von Zeilen mit NaN-Werten, die durch das Rolling entstehen
#print(data[["data","data.1"]].mean(axis=1))
data["temperature_mean"] = data[["data","data.1"]].mean(axis=1)
# Features und Zielvariable definieren
X = data[['battery_voltage', 'battery_current',"temperature_mean"]] #
y = data['battery_soc']
# # Aufteilen der Daten in Trainings- und Testdatensätze # Aufteilen der Daten in Trainings- und Testdatensätze
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42) X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)
# # Modell instanziieren und trainieren # # # Modell instanziieren und trainieren
# battery_model = BatteryModel() #battery_model = BatterySocPredictorGauss()
# battery_model.fit(X_train, y_train) #battery_model.fit(X_train, y_train)
#battery_model.save_model('battery_model.pkl')
# # Modell speichern
# battery_model.save_model('battery_model.pkl')
# # Modell für Vorhersagen laden
# loaded_model = BatteryModel.load_model('battery_model.pkl')
# # Vorhersagen machen
# current_values = np.linspace(-100, 100, 5)
# voltage_range = np.linspace(48, 58, 50)
# for current in current_values:
# X_pred = np.column_stack([voltage_range, np.full(voltage_range.shape, current)])
# y_pred, sigma = loaded_model.predict(X_pred)
# # Plotten der mittleren Vorhersage und des Konfidenzintervalls
# plt.plot(voltage_range, y_pred, label=f'Strom = {current:.1f} A')
# plt.fill_between(voltage_range, y_pred - 1.96 * sigma, y_pred + 1.96 * sigma, alpha=0.2)
# # Hinzufügen von Titel und Legende zum Plot
# plt.title('Vorhergesagter SoC als Funktion der Batteriespannung bei verschiedenen Strömen')
# plt.xlabel('Batteriespannung (V)')
# plt.ylabel('State of Charge (SoC %)')
# plt.legend()
# plt.show()
# sys.exit()
# # Daten laden
# data_path = 'train.csv'
# data = pd.read_csv(data_path)
# # Spalten auswählen
# X = data[['battery_voltage', 'battery_current']] # Merkmale
# y = data['battery_soc'] # Zielvariable
# # Aufteilung der Daten in Trainings- und Testset
# # Transformiere die Zielvariable
# y_transformed = np.log(y / (101 - y))
# # X Normalisierung
# scaler = StandardScaler()
# X_scaled = scaler.fit_transform(X)
# # Aufteilen der Daten in Trainings- und Testdatensätze
# X_train, X_test, y_train, y_test = train_test_split(X_scaled, y_transformed, test_size=0.5, random_state=42)
# # Kernel und Modell definieren
# kernel = WhiteKernel(1.0, (1e-7, 1e3)) + RBF(length_scale=(0.1,0.1), length_scale_bounds=((1e-7, 1e3),(1e-7, 1e3))) #* ConstantKernel(constant_value=1.0, constant_value_bounds=(1e-05, 100000.0))
# gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10, alpha=1e-2, normalize_y=True)
# # Modell trainieren
# gp.fit(X_train, y_train)
# # Vorhersagen und Rücktransformieren
# #y_pred_transformed, sigma = gp.predict(X_test, return_std=True)
# #y_pred = 100 / (1 + np.exp(-y_pred_transformed))
# # Ergebnisse anzeigen
# #print("Vorhersagen:", y_pred)
# #print("Unsicherheit der Vorhersagen:", sigma)
# # Angenommen, 'gp' ist dein trainiertes Gaußsches Prozessmodell
# joblib.dump(gp, 'gaussian_process_model.pkl')
# # Festlegen der Ströme und Spannungsrange für die Vorhersagen
# current_values = np.linspace(-100, 100, 5)
# voltage_range = np.linspace(48, 58, 50)
# # Erstellen einer Figur für die Plots
# plt.figure(figsize=(12, 8))
# # Für jeden Stromwert einen Plot erstellen
# for current in current_values:
# # Erstellen von Vorhersagedatenpunkten
# X_pred = np.column_stack([voltage_range, np.full(voltage_range.shape, current)])
# X_pred_scaled = scaler.transform(X_pred) # Standardisierung
# # Vorhersage des SoC und der Unsicherheit battery_model = BatterySocPredictorGauss.load_model('battery_model.pkl')
# y_pred_transformed, sigma_transformed = gp.predict(X_pred_scaled, return_std=True)
# y_pred = 101 / (1 + np.exp(-y_pred_transformed)) # Rücktransformation
# sigmoid_y_pred = 1 / (1 + np.exp(-y_pred_transformed)) # Vorhersagen auf den Testdaten
# sigma = sigma_transformed * 101 * sigmoid_y_pred * (1 - sigmoid_y_pred) y_pred_test = battery_model.predict(X_test)
print(y_pred_test.shape, " ", y_test.shape)
# Berechnung des MAE und RMSE
mae = mean_absolute_error(y_test, y_pred_test)
rmse = mean_squared_error(y_test, y_pred_test, squared=False)
print(f'Mean Absolute Error (MAE): {mae}')
print(f'Root Mean Squared Error (RMSE): {rmse}')
# Plotten der tatsächlichen Werte vs. Vorhersagen
# plt.figure(figsize=(12, 6))
# plt.plot(y_test.values, label='Actual SoC')
# plt.plot(y_pred_test, label='Predicted SoC')
# plt.xlabel('Samples')
# plt.ylabel('State of Charge (SoC)')
# plt.title('Actual vs Predicted SoC')
# plt.legend()
# plt.show()
# # Plotten der mittleren Vorhersage und des Konfidenzintervalls # # # Modell speichern
# plt.plot(voltage_range, y_pred, label=f'Strom = {current:.1f} A') #battery_model.save_model('battery_model.pkl')
# plt.fill_between(voltage_range, y_pred - 1.96 * sigma, y_pred + 1.96 * sigma, alpha=0.2)
# # Hinzufügen von Titel und Legende zum Plot # Modell für Vorhersagen laden
# plt.title('Vorhergesagter SoC als Funktion der Batteriespannung bei verschiedenen Strömen') #loaded_model = BatterySocPredictorGauss.load_model('battery_model.pkl')
# plt.xlabel('Batteriespannung (V)')
# plt.ylabel('State of Charge (SoC %)') ####################
# plt.legend() # LSTM
# plt.show() ####################
predictor = BatterySoCPredictorLSTM(gauss='battery_model.pkl')
# # Training mit rekursiver Vorhersage
predictor.fit(train_data_path, epochs=50, batch_size=50, validation_split=0.1)
# # # Speichern des Modells und der Scaler
predictor.save_model(model_path=model_path, scaler_path=scaler_path)
# # # Laden des Modells und der Scaler
loaded_predictor = BatterySoCPredictorLSTM(model_path=model_path, scaler_path=scaler_path,gauss='battery_model.pkl')
test_data = pd.read_csv(test_data_path)
test_data['Time'] = pd.to_datetime(test_data['Time'], unit='ms')
test_data.set_index('Time', inplace=True)
test_data.replace('undefined', np.nan, inplace=True)
test_data.dropna(inplace=True)
test_data['battery_voltage'] = pd.to_numeric(test_data['battery_voltage'], errors='coerce')
test_data['battery_current'] = pd.to_numeric(test_data['battery_current'], errors='coerce')
test_data['battery_soc'] = pd.to_numeric(test_data['battery_soc'], errors='coerce')
test_data['data'] = pd.to_numeric(test_data['data.1'], errors='coerce')
test_data.dropna(inplace=True)
scaled_test_data = loaded_predictor.scaler.transform(test_data[['battery_voltage', 'battery_current', 'data', 'battery_soc']])
test_data['scaled_soc'] = loaded_predictor.target_scaler.transform(test_data[['battery_soc']])
test_data.dropna(inplace=True)
X_test, y_test = loaded_predictor._create_sequences(scaled_test_data, loaded_predictor.seq_length, loaded_predictor.n_future_steps)
predictions = loaded_predictor.model.predict(X_test)
predictions = loaded_predictor.target_scaler.inverse_transform(predictions.reshape(-1, 1)).reshape(-1, loaded_predictor.n_future_steps)
# print(test_data['battery_soc'].values[5:-5,...].shape)
# print(predictions[:,0].shape)
test_data_y = test_data['battery_soc'].values[5:-1,...]
mae = mean_absolute_error(test_data_y, predictions[:,0])
rmse = mean_squared_error(test_data_y, predictions[:,0], squared=False)
print(f'Mean Absolute Error (MAE): {mae}')
print(f'Root Mean Squared Error (RMSE): {rmse}')
plt.figure(figsize=(12, 6))
plt.plot(test_data_y, label='Actual SoC')
plt.plot(predictions[:,0].flatten(), label='Predicted SoC')
plt.xlabel('Samples')
plt.ylabel('State of Charge (SoC)')
plt.title('Actual vs Predicted SoC using LSTM')
plt.legend()
plt.show()

View File

@ -60,7 +60,6 @@ class EnergieManagementSystem:
# Berechnet das Ende basierend auf der Länge der Lastkurve # Berechnet das Ende basierend auf der Länge der Lastkurve
for stunde in range(start_stunde, ende): for stunde in range(start_stunde, ende):
# Anpassung, um sicherzustellen, dass Indizes korrekt sind # Anpassung, um sicherzustellen, dass Indizes korrekt sind
verbrauch = lastkurve_wh[stunde] verbrauch = lastkurve_wh[stunde]
if self.haushaltsgeraet != None: if self.haushaltsgeraet != None:
@ -104,6 +103,7 @@ class EnergieManagementSystem:
eauto_soc_pro_stunde.append(eauto_soc) eauto_soc_pro_stunde.append(eauto_soc)
akku_soc_pro_stunde.append(self.akku.ladezustand_in_prozent()) akku_soc_pro_stunde.append(self.akku.ladezustand_in_prozent())
kosten_euro_pro_stunde.append(stündliche_kosten_euro) kosten_euro_pro_stunde.append(stündliche_kosten_euro)
einnahmen_euro_pro_stunde.append(stündliche_einnahmen_euro) einnahmen_euro_pro_stunde.append(stündliche_einnahmen_euro)

View File

@ -10,7 +10,7 @@ class Wechselrichter:
eigenverbrauch = 0.0 eigenverbrauch = 0.0
#eigenverbrauch = min(erzeugung, verbrauch) # Direkt verbrauchte Energie #eigenverbrauch = min(erzeugung, verbrauch) # Direkt verbrauchte Energie
if erzeugung > verbrauch: if erzeugung >= verbrauch:
if verbrauch > self.max_leistung_wh: if verbrauch > self.max_leistung_wh:
verluste += erzeugung - self.max_leistung_wh verluste += erzeugung - self.max_leistung_wh
@ -29,7 +29,7 @@ class Wechselrichter:
restleistung_nach_verbrauch = erzeugung-verbrauch #min(self.max_leistung_wh - verbrauch, erzeugung-verbrauch) restleistung_nach_verbrauch = erzeugung-verbrauch #min(self.max_leistung_wh - verbrauch, erzeugung-verbrauch)
# Akku # Akku
geladene_energie, verluste_laden_akku = self.akku.energie_laden(restleistung_nach_verbrauch, hour) geladene_energie, verluste_laden_akku = self.akku.energie_laden(restleistung_nach_verbrauch, hour)
rest_überschuss = restleistung_nach_verbrauch - geladene_energie rest_überschuss = restleistung_nach_verbrauch - (geladene_energie+verluste_laden_akku)
# if hour == 12: # if hour == 12:
# print("Erzeugung:",erzeugung) # print("Erzeugung:",erzeugung)
# print("Last:",verbrauch) # print("Last:",verbrauch)
@ -38,12 +38,14 @@ class Wechselrichter:
# print("RestÜberschuss"," - ",rest_überschuss) # print("RestÜberschuss"," - ",rest_überschuss)
# print("RestLesitung WR:",self.max_leistung_wh - verbrauch) # print("RestLesitung WR:",self.max_leistung_wh - verbrauch)
# Einspeisung, restliche WR Kapazität # Einspeisung, restliche WR Kapazität
if rest_überschuss > self.max_leistung_wh - verbrauch: if rest_überschuss > self.max_leistung_wh - verbrauch:
netzeinspeisung = self.max_leistung_wh - verbrauch netzeinspeisung = self.max_leistung_wh - verbrauch
verluste += rest_überschuss - netzeinspeisung verluste += rest_überschuss - netzeinspeisung
else: else:
netzeinspeisung = rest_überschuss netzeinspeisung = rest_überschuss
#if hour ==10:
# print(rest_überschuss," ",restleistung_nach_verbrauch, " Gela:",geladene_energie," Ver:",verluste_laden_akku)
verluste += verluste_laden_akku verluste += verluste_laden_akku

View File

@ -4,7 +4,6 @@ from modules.class_load import *
from modules.class_ems import * from modules.class_ems import *
from modules.class_pv_forecast import * from modules.class_pv_forecast import *
from modules.class_akku import * from modules.class_akku import *
from modules.class_strompreis import *
from modules.class_heatpump import * from modules.class_heatpump import *
from modules.class_load_container import * from modules.class_load_container import *
from modules.class_inverter import * from modules.class_inverter import *
@ -237,11 +236,7 @@ class optimization_problem:
############### ###############
# Strompreise # Strompreise
############### ###############
filepath = os.path.join (r'test_data', r'strompreise_akkudokAPI.json') # Pfad zur JSON-Datei anpassen specific_date_prices = parameter["strompreis_euro_pro_wh"]
#price_forecast = HourlyElectricityPriceForecast(source=filepath)
price_forecast = HourlyElectricityPriceForecast(source="https://api.akkudoktor.net/prices?start="+date_now+"&end="+date+"", prediction_hours=self.prediction_hours)
specific_date_prices = price_forecast.get_price_for_daterange(date_now,date)
#print(price_forecast)
print(specific_date_prices) print(specific_date_prices)
#print("https://api.akkudoktor.net/prices?start="+date_now+"&end="+date) #print("https://api.akkudoktor.net/prices?start="+date_now+"&end="+date)
@ -289,8 +284,22 @@ class optimization_problem:
visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,best_solution[0::2],best_solution[1::2] , temperature_forecast, start_hour, self.prediction_hours,einspeiseverguetung_euro_pro_wh,extra_data=extra_data) visualisiere_ergebnisse(gesamtlast, pv_forecast, specific_date_prices, o,best_solution[0::2],best_solution[1::2] , temperature_forecast, start_hour, self.prediction_hours,einspeiseverguetung_euro_pro_wh,extra_data=extra_data)
os.system("cp visualisierungsergebnisse.pdf ~/") os.system("cp visualisierungsergebnisse.pdf ~/")
# 'Eigenverbrauch_Wh_pro_Stunde': eigenverbrauch_wh_pro_stunde,
# 'Netzeinspeisung_Wh_pro_Stunde': netzeinspeisung_wh_pro_stunde,
# 'Netzbezug_Wh_pro_Stunde': netzbezug_wh_pro_stunde,
# 'Kosten_Euro_pro_Stunde': kosten_euro_pro_stunde,
# 'akku_soc_pro_stunde': akku_soc_pro_stunde,
# 'Einnahmen_Euro_pro_Stunde': einnahmen_euro_pro_stunde,
# 'Gesamtbilanz_Euro': gesamtkosten_euro,
# 'E-Auto_SoC_pro_Stunde':eauto_soc_pro_stunde,
# 'Gesamteinnahmen_Euro': sum(einnahmen_euro_pro_stunde),
# 'Gesamtkosten_Euro': sum(kosten_euro_pro_stunde),
# "Verluste_Pro_Stunde":verluste_wh_pro_stunde,
# "Gesamt_Verluste":sum(verluste_wh_pro_stunde),
# "Haushaltsgeraet_wh_pro_stunde":haushaltsgeraet_wh_pro_stunde
#print(eauto) #print(eauto)
return {"discharge_hours_bin":discharge_hours_bin, "eautocharge_hours_float":eautocharge_hours_float ,"result":o ,"eauto_obj":eauto,"start_solution":best_solution,"spuelstart":spuelstart_int} return {"discharge_hours_bin":discharge_hours_bin, "eautocharge_hours_float":eautocharge_hours_float ,"result":o ,"eauto_obj":eauto,"start_solution":best_solution,"spuelstart":spuelstart_int,"simulation_data":o}

View File

@ -29,7 +29,7 @@ def repeat_to_shape(array, target_shape):
class HourlyElectricityPriceForecast: class HourlyElectricityPriceForecast:
def __init__(self, source, cache_dir='cache', abgaben=0.000, prediction_hours=24): #228 def __init__(self, source, cache_dir='cache', abgaben=0.000228, prediction_hours=24): #228
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)