mirror of
https://github.com/Akkudoktor-EOS/EOS.git
synced 2025-04-19 08:55:15 +00:00
Strompreis entkoppelt, kann jetzt als Array übergeben werden.
This commit is contained in:
parent
2605460a99
commit
5e842d5ee4
@ -8,6 +8,7 @@ from modules.class_strompreis import *
|
||||
from modules.class_heatpump import *
|
||||
from modules.class_load_container import *
|
||||
from modules.class_sommerzeit import *
|
||||
from modules.class_soc_calc import *
|
||||
from modules.visualize import *
|
||||
from modules.class_battery_soc_predictor import *
|
||||
import os
|
||||
@ -23,38 +24,56 @@ from modules.class_optimize import *
|
||||
import numpy as np
|
||||
import random
|
||||
import os
|
||||
from config import *
|
||||
|
||||
app = Flask(__name__)
|
||||
|
||||
|
||||
opt_class = optimization_problem(prediction_hours=48, strafe=10)
|
||||
soc_predictor = BatterySocPredictor.load_model('battery_model.pkl')
|
||||
|
||||
|
||||
|
||||
|
||||
@app.route('/soc', methods=['GET'])
|
||||
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
|
||||
x = np.array( [[float(voltage), float(current)]] )
|
||||
# MariaDB Verbindungsdetails
|
||||
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
|
||||
ergebnis = soc_predictor.predict(x)
|
||||
print(ergebnis)
|
||||
|
||||
return jsonify(ergebnis)
|
||||
return jsonify("Done")
|
||||
|
||||
|
||||
@app.route('/strompreis', methods=['GET'])
|
||||
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'])
|
||||
@ -63,7 +82,7 @@ def flask_optimize():
|
||||
parameter = request.json
|
||||
|
||||
# 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:
|
||||
if p not in parameter:
|
||||
return jsonify({"error": f"Fehlender Parameter: {p}"}), 400
|
||||
|
@ -1,6 +1,6 @@
|
||||
import numpy as np
|
||||
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
|
||||
self.kapazitaet_wh = kapazitaet_wh
|
||||
# Initialer Ladezustand des Akkus in Wh
|
||||
|
@ -1,20 +1,37 @@
|
||||
import numpy as np
|
||||
import pandas as pd
|
||||
import joblib
|
||||
import joblib, json
|
||||
from sklearn.preprocessing import StandardScaler
|
||||
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 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 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):
|
||||
# Initialisierung von Scaler und Gaußschem Prozessmodell
|
||||
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)))
|
||||
self.gp = GaussianProcessRegressor(kernel=kernel, n_restarts_optimizer=10, alpha=1e-2, normalize_y=True)
|
||||
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-3, normalize_y=True)
|
||||
|
||||
def fit(self, X, y):
|
||||
# Transformiere die Zielvariable
|
||||
@ -34,7 +51,7 @@ class BatterySocPredictor:
|
||||
# Rücktransformieren der Unsicherheiten
|
||||
sigmoid_y_pred = 1 / (1 + np.exp(-y_pred_transformed))
|
||||
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):
|
||||
# Speichere das gesamte Modell-Objekt
|
||||
@ -44,132 +61,243 @@ class BatterySocPredictor:
|
||||
def load_model(file_path):
|
||||
# Lade das Modell-Objekt
|
||||
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'
|
||||
# data = pd.read_csv(data_path)
|
||||
# X = data[['battery_voltage', 'battery_current']]
|
||||
# y = data['battery_soc']
|
||||
####################
|
||||
# GAUSS + K-Means
|
||||
####################
|
||||
# Daten laden und vorbereiten
|
||||
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
|
||||
# X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.1, random_state=42)
|
||||
# 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)
|
||||
|
||||
# # Modell instanziieren und trainieren
|
||||
# battery_model = BatteryModel()
|
||||
# battery_model.fit(X_train, y_train)
|
||||
|
||||
# # 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
|
||||
# # # Modell instanziieren und trainieren
|
||||
#battery_model = BatterySocPredictorGauss()
|
||||
#battery_model.fit(X_train, y_train)
|
||||
#battery_model.save_model('battery_model.pkl')
|
||||
|
||||
# # Vorhersage des SoC und der Unsicherheit
|
||||
# y_pred_transformed, sigma_transformed = gp.predict(X_pred_scaled, return_std=True)
|
||||
# y_pred = 101 / (1 + np.exp(-y_pred_transformed)) # Rücktransformation
|
||||
battery_model = BatterySocPredictorGauss.load_model('battery_model.pkl')
|
||||
|
||||
# sigmoid_y_pred = 1 / (1 + np.exp(-y_pred_transformed))
|
||||
# sigma = sigma_transformed * 101 * sigmoid_y_pred * (1 - sigmoid_y_pred)
|
||||
# Vorhersagen auf den Testdaten
|
||||
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
|
||||
# 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)
|
||||
# # # Modell speichern
|
||||
#battery_model.save_model('battery_model.pkl')
|
||||
|
||||
# # 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()
|
||||
# Modell für Vorhersagen laden
|
||||
#loaded_model = BatterySocPredictorGauss.load_model('battery_model.pkl')
|
||||
|
||||
####################
|
||||
# LSTM
|
||||
####################
|
||||
|
||||
|
||||
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()
|
||||
|
@ -60,7 +60,6 @@ class EnergieManagementSystem:
|
||||
|
||||
# Berechnet das Ende basierend auf der Länge der Lastkurve
|
||||
for stunde in range(start_stunde, ende):
|
||||
|
||||
# Anpassung, um sicherzustellen, dass Indizes korrekt sind
|
||||
verbrauch = lastkurve_wh[stunde]
|
||||
if self.haushaltsgeraet != None:
|
||||
@ -104,6 +103,7 @@ class EnergieManagementSystem:
|
||||
eauto_soc_pro_stunde.append(eauto_soc)
|
||||
|
||||
akku_soc_pro_stunde.append(self.akku.ladezustand_in_prozent())
|
||||
|
||||
kosten_euro_pro_stunde.append(stündliche_kosten_euro)
|
||||
einnahmen_euro_pro_stunde.append(stündliche_einnahmen_euro)
|
||||
|
||||
|
@ -10,7 +10,7 @@ class Wechselrichter:
|
||||
eigenverbrauch = 0.0
|
||||
#eigenverbrauch = min(erzeugung, verbrauch) # Direkt verbrauchte Energie
|
||||
|
||||
if erzeugung > verbrauch:
|
||||
if erzeugung >= verbrauch:
|
||||
if verbrauch > 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)
|
||||
# Akku
|
||||
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:
|
||||
# print("Erzeugung:",erzeugung)
|
||||
# print("Last:",verbrauch)
|
||||
@ -38,12 +38,14 @@ class Wechselrichter:
|
||||
# print("RestÜberschuss"," - ",rest_überschuss)
|
||||
# print("RestLesitung WR:",self.max_leistung_wh - verbrauch)
|
||||
# Einspeisung, restliche WR Kapazität
|
||||
|
||||
if rest_überschuss > self.max_leistung_wh - verbrauch:
|
||||
netzeinspeisung = self.max_leistung_wh - verbrauch
|
||||
verluste += rest_überschuss - netzeinspeisung
|
||||
else:
|
||||
netzeinspeisung = rest_überschuss
|
||||
|
||||
#if hour ==10:
|
||||
# print(rest_überschuss," ",restleistung_nach_verbrauch, " Gela:",geladene_energie," Ver:",verluste_laden_akku)
|
||||
verluste += verluste_laden_akku
|
||||
|
||||
|
||||
|
@ -4,7 +4,6 @@ from modules.class_load import *
|
||||
from modules.class_ems import *
|
||||
from modules.class_pv_forecast import *
|
||||
from modules.class_akku import *
|
||||
from modules.class_strompreis import *
|
||||
from modules.class_heatpump import *
|
||||
from modules.class_load_container import *
|
||||
from modules.class_inverter import *
|
||||
@ -237,11 +236,7 @@ class optimization_problem:
|
||||
###############
|
||||
# Strompreise
|
||||
###############
|
||||
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=self.prediction_hours)
|
||||
specific_date_prices = price_forecast.get_price_for_daterange(date_now,date)
|
||||
#print(price_forecast)
|
||||
specific_date_prices = parameter["strompreis_euro_pro_wh"]
|
||||
print(specific_date_prices)
|
||||
#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)
|
||||
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)
|
||||
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}
|
||||
|
||||
|
||||
|
||||
|
@ -29,7 +29,7 @@ def repeat_to_shape(array, target_shape):
|
||||
|
||||
|
||||
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
|
||||
if not os.path.exists(self.cache_dir):
|
||||
os.makedirs(self.cache_dir)
|
||||
|
Loading…
x
Reference in New Issue
Block a user