mirror of
				https://github.com/Akkudoktor-EOS/EOS.git
				synced 2025-10-30 22:36:21 +00:00 
			
		
		
		
	AC Charge Bug, Price Cache On/Off
This commit is contained in:
		| @@ -95,21 +95,13 @@ class EnergieManagementSystem: | ||||
|                 haushaltsgeraet_wh_pro_stunde[stunde_since_now] = ha_load | ||||
|  | ||||
|             # E-Auto handling | ||||
|             if self.eauto: | ||||
|             if self.eauto and self.ev_charge_hours[stunde]>0: | ||||
|                 geladene_menge_eauto, verluste_eauto = self.eauto.energie_laden(None, stunde, relative_power=self.ev_charge_hours[stunde]) | ||||
|                 # if self.ev_charge_hours[stunde] > 0.0: | ||||
|                 #     print(self.ev_charge_hours[stunde], " ", geladene_menge_eauto," ", self.eauto.ladezustand_in_prozent()) | ||||
|                 verbrauch += geladene_menge_eauto | ||||
|                 verluste_wh_pro_stunde[stunde_since_now] += verluste_eauto | ||||
|                  | ||||
|             if self.eauto: | ||||
|                 eauto_soc_pro_stunde[stunde_since_now] = self.eauto.ladezustand_in_prozent() | ||||
|  | ||||
|             # AC PV Battery Charge | ||||
|             if self.ac_charge_hours[stunde] > 0.0: | ||||
|                 self.akku.set_charge_allowed_for_hour(self.ac_charge_hours[stunde],stunde) | ||||
|                 geladene_menge, verluste_wh = self.akku.energie_laden(None,stunde,relative_power=self.ac_charge_hours[stunde]) | ||||
|                 verbrauch += geladene_menge | ||||
|                 verluste_wh_pro_stunde[stunde_since_now] += verluste_wh     | ||||
|  | ||||
|             # Process inverter logic | ||||
|             erzeugung = self.pv_prognose_wh[stunde] | ||||
|             self.akku.set_charge_allowed_for_hour(self.dc_charge_hours[stunde],stunde) | ||||
| @@ -117,7 +109,14 @@ class EnergieManagementSystem: | ||||
|                 self.wechselrichter.energie_verarbeiten(erzeugung, verbrauch, stunde) | ||||
|             ) | ||||
|  | ||||
|    | ||||
|             # AC PV Battery Charge | ||||
|             if self.ac_charge_hours[stunde] > 0.0: | ||||
|                 self.akku.set_charge_allowed_for_hour(1,stunde) | ||||
|                 geladene_menge, verluste_wh = self.akku.energie_laden(None,stunde,relative_power=self.ac_charge_hours[stunde]) | ||||
|                 #print(stunde, " ", geladene_menge, " ",self.ac_charge_hours[stunde]," ",self.akku.ladezustand_in_prozent()) | ||||
|                 verbrauch += geladene_menge | ||||
|                 netzbezug +=geladene_menge | ||||
|                 verluste_wh_pro_stunde[stunde_since_now] += verluste_wh       | ||||
|  | ||||
|             netzeinspeisung_wh_pro_stunde[stunde_since_now] = netzeinspeisung | ||||
|             netzbezug_wh_pro_stunde[stunde_since_now] = netzbezug | ||||
|   | ||||
| @@ -31,6 +31,7 @@ class optimization_problem: | ||||
|         self.verbose = verbose | ||||
|         self.fix_seed = fixed_seed | ||||
|         self.optimize_ev = True | ||||
|         self.optimize_dc_charge = False | ||||
|  | ||||
|         # Set a fixed seed for random operations if provided | ||||
|         if fixed_seed is not None: | ||||
| @@ -63,7 +64,12 @@ class optimization_problem: | ||||
|         ac_charge = ac_charge / 5.0  # Normalize AC charge to range between 0 and 1 | ||||
|  | ||||
|         # Create dc_charge array: 7 = Not allowed (mapped to 0), 8 = Allowed (mapped to 1) | ||||
|         dc_charge = np.where(discharge_hours_bin == 8, 1, 0) | ||||
|         # Create dc_charge array: Only if DC charge optimization is enabled | ||||
|         if self.optimize_dc_charge: | ||||
|             dc_charge = np.where(discharge_hours_bin == 8, 1, 0) | ||||
|         else: | ||||
|             dc_charge = np.ones_like(discharge_hours_bin)  # Set DC charge to 0 if optimization is disabled | ||||
|  | ||||
|  | ||||
|         # Create discharge array: Only consider value 1 (Discharge), set the rest to 0 (binary output) | ||||
|         discharge = np.where(discharge_hours_bin == 1, 1, 0) | ||||
| @@ -95,7 +101,10 @@ class optimization_problem: | ||||
|         charge_discharge_mutated, = self.toolbox.mutate_charge_discharge(charge_discharge_part) | ||||
|          | ||||
|         # Ensure that no invalid states are introduced during mutation (valid values: 0-8) | ||||
|         charge_discharge_mutated = np.clip(charge_discharge_mutated, 0, 8) | ||||
|         if self.optimize_dc_charge: | ||||
|             charge_discharge_mutated = np.clip(charge_discharge_mutated, 0, 8) | ||||
|         else: | ||||
|             charge_discharge_mutated = np.clip(charge_discharge_mutated, 0, 6) | ||||
|          | ||||
|         # Use split_charge_discharge to split the mutated array into AC charge, DC charge, and discharge components | ||||
|         #ac_charge, dc_charge, discharge = self.split_charge_discharge(charge_discharge_mutated) | ||||
| @@ -190,7 +199,11 @@ class optimization_problem: | ||||
|  | ||||
|         # Initialize toolbox with attributes and operations | ||||
|         self.toolbox = base.Toolbox() | ||||
|         self.toolbox.register("attr_discharge_state", random.randint, 0,11) | ||||
|         if self.optimize_dc_charge: | ||||
|             self.toolbox.register("attr_discharge_state", random.randint, 0,8) | ||||
|         else: | ||||
|             self.toolbox.register("attr_discharge_state", random.randint, 0,6) | ||||
|  | ||||
|         if self.optimize_ev: | ||||
|             self.toolbox.register("attr_ev_charge_index", random.randint, 0, len(possible_ev_charge_currents) - 1) | ||||
|         self.toolbox.register("attr_int", random.randint, start_hour, 23) | ||||
| @@ -205,7 +218,10 @@ class optimization_problem: | ||||
|         #self.toolbox.register("mutate", tools.mutFlipBit, indpb=0.1) | ||||
|         # Register separate mutation functions for each type of value: | ||||
|         # - Discharge state mutation (-5, 0, 1) | ||||
|         self.toolbox.register("mutate_charge_discharge", tools.mutUniformInt, low=0, up=8, indpb=0.1) | ||||
|         if self.optimize_dc_charge: | ||||
|             self.toolbox.register("mutate_charge_discharge", tools.mutUniformInt, low=0, up=8, indpb=0.1) | ||||
|         else: | ||||
|             self.toolbox.register("mutate_charge_discharge", tools.mutUniformInt, low=0, up=6, indpb=0.1) | ||||
|         # - Float mutation for EV charging values | ||||
|         self.toolbox.register("mutate_ev_charge_index", tools.mutUniformInt, low=0, up=len(possible_ev_charge_currents) - 1, indpb=0.1) | ||||
|         # - Start hour mutation for household devices | ||||
| @@ -234,7 +250,9 @@ class optimization_problem: | ||||
|  | ||||
|  | ||||
|         ems.set_akku_discharge_hours(discharge) | ||||
|         ems.set_akku_dc_charge_hours(dc) | ||||
|         # Set DC charge hours only if DC optimization is enabled | ||||
|         if self.optimize_dc_charge: | ||||
|             ems.set_akku_dc_charge_hours(dc) | ||||
|         ems.set_akku_ac_charge_hours(ac) | ||||
|  | ||||
|         if self.optimize_ev: | ||||
| @@ -242,8 +260,8 @@ class optimization_problem: | ||||
|                 possible_ev_charge_currents[i] for i in eautocharge_hours_index | ||||
|             ]             | ||||
|             ems.set_ev_charge_hours(eautocharge_hours_float) | ||||
|         #else: | ||||
|         #    ems.set_ev_charge_hours(np.full(self.prediction_hours, 0 )) | ||||
|         else: | ||||
|             ems.set_ev_charge_hours(np.full(self.prediction_hours, 0 )) | ||||
|         return ems.simuliere(start_hour) | ||||
|  | ||||
|     def evaluate( | ||||
| @@ -284,8 +302,11 @@ class optimization_problem: | ||||
|         ) | ||||
|  | ||||
|         # Adjust total balance with battery value and penalties for unmet SOC | ||||
|          | ||||
|         restwert_akku = ems.akku.aktueller_energieinhalt() * parameter["preis_euro_pro_wh_akku"] | ||||
|         #print(ems.akku.aktueller_energieinhalt()," * ", parameter["preis_euro_pro_wh_akku"] , " ", restwert_akku, " ", gesamtbilanz)  | ||||
|         gesamtbilanz += -restwert_akku | ||||
|         #print(gesamtbilanz) | ||||
|         if self.optimize_ev: | ||||
|             gesamtbilanz +=  max( | ||||
|                     0, | ||||
| @@ -318,8 +339,8 @@ class optimization_problem: | ||||
|             self.toolbox, | ||||
|             mu=100, | ||||
|             lambda_=150, | ||||
|             cxpb=0.7, | ||||
|             mutpb=0.3, | ||||
|             cxpb=0.6, | ||||
|             mutpb=0.4, | ||||
|             ngen=ngen, | ||||
|             stats=stats, | ||||
|             halloffame=hof, | ||||
| @@ -412,8 +433,8 @@ class optimization_problem: | ||||
|         discharge_hours_bin, eautocharge_hours_float, spuelstart_int = self.split_individual( | ||||
|             start_solution | ||||
|         ) | ||||
|  | ||||
|  | ||||
|         if self.optimize_ev: | ||||
|             eautocharge_hours_float = [possible_ev_charge_currents[i] for i in eautocharge_hours_float] | ||||
|  | ||||
|         ac_charge, dc_charge, discharge = self.decode_charge_discharge(discharge_hours_bin) | ||||
|         # Visualize the results | ||||
|   | ||||
| @@ -5,7 +5,6 @@ import matplotlib.pyplot as plt | ||||
| import numpy as np | ||||
| import pandas as pd | ||||
|  | ||||
|  | ||||
| class BatteryDataProcessor: | ||||
|     def __init__( | ||||
|         self, | ||||
| @@ -235,7 +234,7 @@ class BatteryDataProcessor: | ||||
|             marker="o", | ||||
|             label="100% SoC Points", | ||||
|         ) | ||||
|         # plt.scatter(last_points_0_df['timestamp'], last_points_0_df['battery_voltage'], color='red', marker='x', label='0% SoC Points') | ||||
|         plt.scatter(last_points_0_df['timestamp'], last_points_0_df['battery_voltage'], color='red', marker='x', label='0% SoC Points') | ||||
|         plt.xlabel("Timestamp") | ||||
|         plt.ylabel("Voltage (V)") | ||||
|         plt.legend() | ||||
| @@ -255,7 +254,7 @@ class BatteryDataProcessor: | ||||
|             marker="o", | ||||
|             label="100% SoC Points", | ||||
|         ) | ||||
|         # plt.scatter(last_points_0_df['timestamp'], last_points_0_df['battery_current'], color='red', marker='x', label='0% SoC Points') | ||||
|         plt.scatter(last_points_0_df['timestamp'], last_points_0_df['battery_current'], color='red', marker='x', label='0% SoC Points') | ||||
|         plt.xlabel("Timestamp") | ||||
|         plt.ylabel("Current (A)") | ||||
|         plt.legend() | ||||
| @@ -281,17 +280,23 @@ class BatteryDataProcessor: | ||||
|  | ||||
| if __name__ == "__main__": | ||||
|     # MariaDB Verbindungsdetails | ||||
|     config = {} | ||||
|  | ||||
|     config = { | ||||
|         'user': 'soc', | ||||
|         'password': 'Rayoflight123!', | ||||
|         'host': '192.168.1.135', | ||||
|         'database': 'sensor' | ||||
|     } | ||||
|  | ||||
|     # Parameter festlegen | ||||
|     voltage_high_threshold = 55.4  # 100% SoC | ||||
|     voltage_low_threshold = 46.5  # 0% SoC | ||||
|     voltage_low_threshold = 48  # 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 | ||||
|     bat_capacity = 0.8*33 * 1000 / 48 | ||||
|  | ||||
|     # Zeitpunkt X definieren | ||||
|     zeitpunkt_x = (datetime.now() - timedelta(weeks=100)).strftime("%Y-%m-%d %H:%M:%S") | ||||
|     zeitpunkt_x = (datetime.now() - timedelta(weeks=4)).strftime("%Y-%m-%d %H:%M:%S") | ||||
|  | ||||
|     # BatteryDataProcessor instanziieren und verwenden | ||||
|     processor = BatteryDataProcessor( | ||||
| @@ -310,7 +315,7 @@ if __name__ == "__main__": | ||||
|         last_points_100_df, last_points_0_df | ||||
|     ) | ||||
|     # soh_df = processor.calculate_soh(integration_results) | ||||
|     processor.update_database_with_soc(soc_df) | ||||
|     #processor.update_database_with_soc(soc_df) | ||||
|  | ||||
|     processor.plot_data(last_points_100_df, last_points_0_df, soc_df) | ||||
|  | ||||
|   | ||||
| @@ -22,18 +22,20 @@ def repeat_to_shape(array, target_shape): | ||||
|  | ||||
|  | ||||
| class HourlyElectricityPriceForecast: | ||||
|     def __init__(self, source, cache_dir="cache", charges=0.000228, prediction_hours=24):  # 228 | ||||
|     def __init__(self, source, cache_dir="cache", charges=0.000228, prediction_hours=24, cache=True):  # 228 | ||||
|         self.cache_dir = cache_dir | ||||
|         self.cache=cache | ||||
|         os.makedirs(self.cache_dir, exist_ok=True) | ||||
|         self.cache_time_file = os.path.join(self.cache_dir, "cache_timestamp.txt") | ||||
|         self.prices = self.load_data(source) | ||||
|         self.charges = charges | ||||
|         self.prediction_hours = prediction_hours | ||||
|          | ||||
|  | ||||
|     def load_data(self, source): | ||||
|         cache_filename = self.get_cache_filename(source) | ||||
|         if source.startswith("http"): | ||||
|             if os.path.exists(cache_filename) and not self.is_cache_expired(): | ||||
|             if os.path.exists(cache_filename) and not self.is_cache_expired() and self.cache==True: | ||||
|                 print("Loading data from cache...") | ||||
|                 with open(cache_filename, "r") as file: | ||||
|                     json_data = json.load(file) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user