def stop_name_servers(redisDB): if IDStatusManager.number_of_active_ids_redis(redisDB) == 0: pid = redisDB.get(Constants.name_server_key) PyroServerManagement.os_proc_stop(redisDB, pid, "name server", Constants.name_server_key) pid = redisDB.get(Constants.dispatch_server_key) PyroServerManagement.os_proc_stop(redisDB, pid, "dispatch server", Constants.dispatch_server_key)
def stop(self, id): logger.debug("Stop signal received") logger.debug("This is the factory object: " + str(self.get(id))) if self.factory[id]: IDStatusManager.persist_id(id, False, None, self.redisDB) self.factory[id].stopOptControllerThread() del self.factory[id] del self.statusThread[id] #self.stop_pyro_servers() #self.stop_name_servers() self.set_isRunning(id, False) message = "System stopped succesfully" self.redisDB.set("run:" + id, "stopped") logger.debug(message) gc.collect() else: message = "No threads found" logger.debug(message)
def restart_ids(self, wait_time_between_instances): time.sleep(5) old_ids, stopped_ids = IDStatusManager.instances_to_restart( self.redisDB) ids_to_be_restarted = {} for s in old_ids: val = json.loads(s) if "priority" in val.keys(): priority = val["priority"] else: val["priority"] = -1 priority = -1 if priority not in ids_to_be_restarted.keys(): ids_to_be_restarted[priority] = [] ids_to_be_restarted[priority].append(val) ids_to_be_restarted = { k: v for k, v in sorted(ids_to_be_restarted.items(), key=lambda item: item[0]) } print(ids_to_be_restarted) for key, value in ids_to_be_restarted.items(): if key == -1: continue for val in value: try: self.start(val["id"], None, val, restart=True) time.sleep(wait_time_between_instances) except (InvalidModelException, MissingKeysException, InvalidMQTTHostException) as e: # TODO: should we catch these exceptions here? logger.error("Error " + str(e)) self.redisDB.set("run:" + val["id"], "stopped") return str(e) if -1 in ids_to_be_restarted.keys(): value = ids_to_be_restarted[-1] for val in value: try: self.start(val["id"], None, val, restart=True) time.sleep(wait_time_between_instances) except (InvalidModelException, MissingKeysException, InvalidMQTTHostException) as e: # TODO: should we catch these exceptions here? logger.error("Error " + str(e)) self.redisDB.set("run:" + val["id"], "stopped") return str(e) for s in stopped_ids: val = json.loads(s) id = val["id"] self.redisDB.set("run:" + id, "stopped") self.redisDB.set(Constants.id_meta + ":" + id, json.dumps(val))
def restart_ids(self): old_ids, stopped_ids = IDStatusManager.instances_to_restart( self.redisDB) for s in old_ids: val = json.loads(s) try: self.start(val["id"], None, val) except (InvalidModelException, MissingKeysException, InvalidMQTTHostException) as e: # TODO: should we catch these exceptions here? logger.error("Error " + str(e)) self.redisDB.set("run:" + val["id"], "stopped") return str(e) for s in stopped_ids: val = json.loads(s) id = val["id"] self.redisDB.set("run:" + id, "stopped") self.redisDB.set(Constants.id_meta + ":" + id, json.dumps(val))
def start_pryo_mip_servers(redisDB, base_num_of_servers): active_pyro_servers = PyroServerManagement.active_pyro_mip_servers( redisDB) for i in range(base_num_of_servers - active_pyro_servers): PyroServerManagement.start_pyro_mip_server(active_pyro_servers, i, redisDB) while True: active_pyro_servers = PyroServerManagement.active_pyro_mip_servers( redisDB) required = IDStatusManager.num_of_required_pyro_mip_servers_redis( redisDB) number_of_servers_to_start = 0 if active_pyro_servers < required: number_of_servers_to_start = required - active_pyro_servers if number_of_servers_to_start + active_pyro_servers < base_num_of_servers: number_of_servers_to_start += base_num_of_servers - ( active_pyro_servers + number_of_servers_to_start) for i in range(number_of_servers_to_start): PyroServerManagement.start_pyro_mip_server( active_pyro_servers, i, redisDB) time.sleep(60)
def stop_pyro_servers(redisDB): logger.info("stop pyro server init") num_of_active_ids = IDStatusManager.number_of_active_ids_redis(redisDB) logger.debug("active ids = " + str(num_of_active_ids)) count = 0 if num_of_active_ids == 0: redisDB.set(Constants.pyro_mip, 0) keys = redisDB.get_keys_for_pattern(Constants.pyro_mip_pid + ":*") if keys is not None: for key in keys: pid = int(redisDB.get(key)) PyroServerManagement.os_proc_stop(redisDB, pid, "mip server " + str(pid), key) count += 1 active_pyro_servers = int(redisDB.get(Constants.pyro_mip, 0)) active_pyro_servers -= count if active_pyro_servers < 0: active_pyro_servers = 0 redisDB.set(Constants.pyro_mip, active_pyro_servers) else: logger.info("keys is none")
def optimize(self, count, solver_name, model_path): infeasibility_repeated = 0 while not self.redisDB.get_bool( self.stop_signal_key): # and not self.stopRequest.isSet(): repeat_flag = False action_handle_map = {} start_time_total = time.time() self.logger.info("waiting for data") data_dict = self.input.get_data( preprocess=False, redisDB=self.redisDB) # blocking call self.logger.debug("Data is: " + json.dumps(data_dict, indent=4)) if self.redisDB.get_bool(self.stop_signal_key) or self.redisDB.get( "End ofw") == "True": break start_time = time.time() # Creating an optimization instance with the referenced model try: optsolver = SolverFactory(solver_name) if solver_name == "ipopt": optsolver.options[ 'max_iter'] = self.solver_ipopt_max_iteration optsolver.options[ 'max_cpu_time'] = self.solver_ipopt_timeout #spec = importlib.util.spec_from_file_location(model_path, model_path) #module = spec.loader.load_module(spec.name) mod = __import__(model_path, fromlist=['Model']) my_class = getattr(mod, 'Model') self.logger.debug("Creating an optimization instance") cnt = 0 instance = my_class.model.create_instance(data_dict) self.logger.debug("instance constructed: " + str(instance.is_constructed()) + " in count " + str(cnt)) result = optsolver.solve(instance, keepfiles=True) except Exception as e: self.logger.error(e) start_time = time.time() - start_time self.logger.info("Time to run optimizer = " + str(start_time) + " sec.") if result and (result.solver.status == SolverStatus.ok) and ( result.solver.termination_condition == TerminationCondition.optimal): # this is feasible and optimal self.logger.info("Solver status and termination condition ok") instance.solutions.load_from(result) try: my_dict = {} for v in instance.component_objects(Var, active=True): # self.logger.debug("Variable in the optimization: "+ str(v)) varobject = getattr(instance, str(v)) var_list = [] try: # Try and add to the dictionary by key ref for index in varobject: var_list.append(varobject[index].value) my_dict[str(v)] = var_list except Exception as e: self.logger.error(e) # Append new index to currently existing items # my_dict = {**my_dict, **{v: list}} self.output.publish_data(self.id, my_dict, self.dT_in_seconds) self.monitor.send_monitor_ping(self.control_frequency) except Exception as e: self.logger.error(e) elif result.solver.termination_condition == TerminationCondition.infeasible: # do something about it? or exit? self.logger.info("Termination condition is infeasible") repeat_flag = True elif result.solver.termination_condition == TerminationCondition.maxIterations: # do something about it? or exit? self.logger.info("Termination condition is maxIteration limit") repeat_flag = True elif result.solver.termination_condition == TerminationCondition.maxTimeLimit: # do something about it? or exit? self.logger.info("Termination condition is maxTimeLimit") repeat_flag = True else: self.logger.info("Nothing fits") self.erase_pyomo_files(self.pyomo_path) if repeat_flag: infeasibility_repeated += 1 if infeasibility_repeated <= self.infeasibility_repetition_count: continue infeasibility_repeated = 0 count += 1 if self.repetition > 0 and count >= self.repetition: self.repetition_completed = True break self.logger.info("Optimization thread going to sleep for " + str(self.control_frequency) + " seconds") time_spent = IDStatusManager.update_count(self.repetition, self.id, self.redisDB) final_time_total = time.time() sleep_time = self.control_frequency - int(final_time_total - start_time_total) self.logger.info("Final time " + str(final_time_total) + " start time " + str(start_time_total) + " run time " + str(int(final_time_total - start_time_total))) self.logger.info("Actual sleep time " + str(sleep_time) + " seconds") if sleep_time > 0: for i in range(sleep_time): time.sleep(1) if self.redisDB.get_bool(self.stop_signal_key): break if self.redisDB.get("End ofw") == "True": break
def optimize(self, count, solver_name, model_path): while not self.redisDB.get_bool(self.stop_signal_key): # and not self.stopRequest.isSet(): self.logger.info("waiting for data") data_dict = self.input.get_data(preprocess=False, redisDB=self.redisDB) # blocking call self.logger.debug("Data is: " + json.dumps(data_dict, indent=4)) if self.redisDB.get_bool(self.stop_signal_key): # or self.stopRequest.isSet(): break start_time = time.time() try: optsolver = SolverFactory(solver_name) if solver_name == "ipopt": optsolver.options['max_iter'] = self.solver_ipopt_max_iteration optsolver.options['max_cpu_time'] = self.solver_ipopt_timeout spec = importlib.util.spec_from_file_location(model_path, model_path) module = spec.loader.load_module(spec.name) my_class = getattr(module, 'Model') self.logger.debug("Creating an optimization instance") instance = my_class.model.create_instance(data_dict) self.logger.info("Instance created with pyomo") result = optsolver.solve(instance) except Exception as e: self.logger.error(e) start_time = time.time() - start_time self.logger.info("Time to run optimizer = " + str(start_time) + " sec.") if result and (result.solver.status == SolverStatus.ok) and ( result.solver.termination_condition == TerminationCondition.optimal): # this is feasible and optimal self.logger.info("Solver status and termination condition ok") self.logger.debug("Results for id: " + str(self.id)) self.logger.debug(result) instance.solutions.load_from(result) try: my_dict = {} for v in instance.component_objects(Var, active=True): # self.logger.debug("Variable in the optimization: "+ str(v)) varobject = getattr(instance, str(v)) var_list = [] try: # Try and add to the dictionary by key ref for index in varobject: var_list.append(varobject[index].value) my_dict[str(v)] = var_list except Exception as e: self.logger.error(e) # Append new index to currently existing items # my_dict = {**my_dict, **{v: list}} if "stop_system" not in my_dict.keys() or ( "stop_system" in my_dict.keys() and my_dict["stop_system"][0] == 0.0): self.logger.debug("model.stop_system false") self.output.publish_data(self.id, my_dict, self.dT_in_seconds) else: self.logger.debug("model.stop_system true") self.monitor.send_monitor_ping(self.control_frequency) except Exception as e: self.logger.error(e) elif self.results.solver.termination_condition == TerminationCondition.infeasible: # do something about it? or exit? self.logger.info("Termination condition is infeasible") else: self.logger.info("Nothing fits") count += 1 if self.repetition > 0 and count >= self.repetition: self.repetition_completed = True break self.logger.info("Optimization thread going to sleep for " + str(self.control_frequency) + " seconds") time_spent = IDStatusManager.update_count(self.repetition, self.id, self.redisDB) for i in range(self.control_frequency - time_spent): time.sleep(1) if self.redisDB.get_bool(self.stop_signal_key) or self.stopRequest.isSet(): break
def optimize(self, count, solver_name, model_path): #self.logger.debug("############## testsf") while not self.redisDB.get_bool( self.stop_signal_key): # and not self.stopRequest.isSet(): start_time_total = time.time() self.logger.debug("number of workers = " + str(self.number_of_workers)) self.logger.info("waiting for data") data_dict = self.input.get_data( preprocess=True, redisDB=self.redisDB) # blocking call self.logger.debug("data_dict after waiting data " + str(data_dict)) if self.redisDB.get_bool(self.stop_signal_key) or self.redisDB.get( "End ofw") == "True": # or self.stopRequest.isSet(): break ###################################### # STOCHASTIC OPTIMIZATION ev_park = self.input.inputPreprocess.ev_park # read from data dict whenever possible max_number_of_cars = ev_park.get_num_of_cars() position_states = [0, 1] vac_soc_states, vac_decision_domain, vac_decision_domain_n = self.calculate_vac_domain( ev_park) self.logger.debug("vac_soc_states " + str(vac_soc_states) + " vac_decision_domain " + str(vac_decision_domain)) ess_soc_states, ess_decision_domain = self.calculate_ess_domain( data_dict) self.logger.debug("ess_soc_states " + str(ess_soc_states) + " ess_decision_domain " + str(ess_decision_domain)) T = self.horizon_in_steps behaviour_model, Value, Decision = self.get_values( T, ess_soc_states, vac_soc_states, position_states, max_number_of_cars) stochastic_start_time = time.time() min_value = 100 * float(data_dict[None]["ESS_Min_SoC"][None]) max_value = 100 * float(data_dict[None]["ESS_Max_SoC"][None]) max_vac_soc_states = max(vac_soc_states) reverse_steps = reversed(range(0, self.horizon_in_steps)) loop_fail = False position_single_ev = int(data_dict[None]["Recharge"][None]) self.logger.debug("Entering to timesteps") self.logger.debug("timeout " + str(self.stochastic_timeout)) for timestep in reverse_steps: if self.redisDB.get_bool( self.stop_signal_key) or self.redisDB.get( "End ofw") == "True": break else: self.logger.info("Timestep :#" + str(timestep)) value_index, value, bm_idx, bm, ess_vac_product = self.calculate_internal_values( timestep, Value, behaviour_model, ess_soc_states, vac_soc_states, position_states) data_dict[None]["Value_Index"] = {None: value_index} data_dict[None]["Value"] = value #self.logger.debug("value "+str(value)) data_dict[None]["Behavior_Model_Index"] = {None: bm_idx} data_dict[None]["Behavior_Model"] = bm data_dict[None]["Timestep"] = {None: timestep} # retrieve the solutions try: """if timestep == (self.horizon_in_steps - 1): self.logger.debug("20 sec sleep. Only once") time.sleep(20)""" with ProcessPool( max_workers=self.number_of_workers) as pool: self.logger.debug("Using pebble") futures = [] if self.single_ev: self.logger.debug( "Entering to ProcessPoolExecutor single ev" ) for combination in ess_vac_product: ini_ess_soc, ini_vac_soc, position = combination futures.append( pool.schedule( OptControllerStochastic. create_instance_and_solve, args=( data_dict, ess_decision_domain, min_value, max_value, vac_decision_domain, vac_decision_domain_n, max_vac_soc_states, ev_park. total_charging_stations_power, timestep, True, solver_name, model_path, ini_ess_soc, ini_vac_soc, position), timeout=self.stochastic_timeout)) else: self.logger.debug( "Entering to ProcessPoolExecutor") for combination in ess_vac_product: ini_ess_soc, ini_vac_soc = combination futures.append( pool.schedule( OptControllerStochastic. create_instance_and_solve, args=( data_dict, ess_decision_domain, min_value, max_value, vac_decision_domain, vac_decision_domain_n, max_vac_soc_states, ev_park. total_charging_stations_power, timestep, False, solver_name, model_path, ini_ess_soc, ini_vac_soc), timeout=self.stochastic_timeout)) iterator = (future.result() for future in futures) while True: try: d, v = next(iterator) if d is None and v is None: loop_fail = True self.logger.error( "Optimization calculation was not possible. Process will be repeated" ) break Value.update(v) Decision.update(d) except StopIteration: break except TimeoutError as error: self.logger.error( "function took longer than %d seconds" % error.args[1]) loop_fail = True except ProcessExpired as error: self.logger.error("%s. Exit code: %d" % (error, error.exitcode)) loop_fail = True except Exception as error: self.logger.error("function raised %s" % error) loop_fail = True print( error.traceback ) # Python's traceback of remote process except Exception as e: self.logger.error(e) loop_fail = True if loop_fail: self.logger.error( "ERROR: Optimization calculation was not possible. Process will be repeated" ) break if loop_fail: self.logger.error("Optimization will be repeated") # erasing files from pyomo #self.erase_pyomo_files(self.pyomo_path) if self.redisDB.get_bool(self.stop_signal_key): break if self.repetition == -1: continue else: break else: self.logger.debug("Flag loop_fail is False") time.sleep(0.2) # erasing files from pyomo #self.erase_pyomo_files(self.pyomo_path) """ with open("/usr/src/app/optimization/resources/Value_p.txt", "w") as f: f.write(str(Value)) self.logger.info("written to file") """ if self.redisDB.get_bool(self.stop_signal_key): break else: initial_ess_soc_value = float( data_dict[None]["SoC_Value"][None]) self.logger.debug("initial_ess_soc_value " + str(initial_ess_soc_value)) initial_vac_soc_value = float( data_dict[None]["VAC_SoC_Value"][None]) self.logger.debug("initial_vac_soc_value " + str(initial_vac_soc_value)) if self.single_ev: self.logger.debug("position_single_ev " + str(position_single_ev)) result_key = (0, initial_ess_soc_value, initial_vac_soc_value, position_single_ev) else: result_key = (0, initial_ess_soc_value, initial_vac_soc_value) p_pv = Decision[result_key]['PV'] p_grid = Decision[result_key]['Grid'] p_ess = Decision[result_key]['ESS'] p_vac = Decision[result_key]['VAC'] if "P_Load" in data_dict[None].keys(): if self.single_ev: p_load = data_dict[None]["P_Load"][0] / 1000 else: p_load = data_dict[None]["P_Load"][0] else: p_load = 0 #Decision.clear() #Value.clear() p_ev = {} self.logger.debug("Dynamic programming calculations") self.logger.debug("PV generation: " + str(p_pv)) self.logger.debug("Grid power: " + str(p_grid)) self.logger.debug("ESS discharge: " + str(p_ess)) self.logger.debug("VAC charging " + str(p_vac)) ############################################################################# # This section distributes virtual capacity charging power into the cars plugged chargers in the station # detect which cars are connected to the chargers in the commercial charging station # calculate the maximum feasible charging power input under given SoC dT = data_dict[None]["dT"][None] ESS_Max_Charge = data_dict[None]["ESS_Max_Charge_Power"][ None] ESS_Capacity = data_dict[None]["ESS_Capacity"][None] connections = ev_park.max_charge_power_calculator(dT) # Calculation of the feasible charging power at the commercial station max_power_for_cars = sum(connections.values()) feasible_ev_charging_power = min(max_power_for_cars, p_vac) self.logger.debug("feasible_ev_charging_power" + str(feasible_ev_charging_power)) self.logger.debug("max_power_for_cars " + str(max_power_for_cars)) for charger, max_charge_power_of_car in connections.items( ): if feasible_ev_charging_power == 0: p_ev[charger] = 0.6 else: power_output_of_charger = feasible_ev_charging_power * ( max_charge_power_of_car / max_power_for_cars) p_ev[charger] = power_output_of_charger # self.logger.debug("power_output_of_charger "+str(power_output_of_charger)+"in charger "+str(charger) ) ############################################################################# ############################################################################# # This section decides what to do with the non utilized virtual capacity charging power if self.repetition == -1: sample_data = {} p_load_var = "P_Load_sample" P_PV_var = "P_PV_sample" sample = self.input.get_sample(p_load_var, self.redisDB) if sample is not None: sample_data.update(sample) sample = self.input.get_sample(P_PV_var, self.redisDB) if sample is not None: sample_data.update(sample) """ sample_data = self.input.get_data_single(redisDB=self.redisDB) # blocking call """ self.logger.debug("single data at this moment " + str(sample_data)) self.logger.debug("data keys " + str(sample_data.keys())) p_ev_single = 0 if not sample_data == None: if not P_PV_var or not p_load_var in sample_data.keys( ): p_pv_now = p_pv p_load_now = p_load self.logger.debug( "Not PV or Load data present") else: for name, value in sample_data.items(): if P_PV_var in name: p_pv_now = value[0] / 1000 self.logger.debug("p_pv_now " + str(p_pv_now)) if p_load_var in name: if self.single_ev: p_load_now = value[0] / 1000 else: p_load_now = value[0] self.logger.debug("p_load_now " + str(p_load_now)) for charger, max_charge_power_of_car in connections.items( ): if charger in p_ev.keys(): p_ev_single += p_ev[charger] if (p_pv_now - p_load_now - p_ev_single) < 0: if p_ess > (p_load_now + p_ev_single - p_pv_now): p_ess = p_load_now + p_ev_single - p_pv_now self.logger.debug( "p_ess output changed to " + str(p_ess) + " kW") else: #if (p_pv_now - p_load_now - p_ev_single) < p_ess: if p_ess > 0: #p_ess = p_pv_now - p_load_now - p_ev_single p_ess = 0 self.logger.debug( "p_ess output changed to " + str(p_ess) + " kW") else: p_ev_single = 0 for charger, max_charge_power_of_car in connections.items( ): if charger in p_ev.keys(): p_ev_single += p_ev[charger] self.logger.debug("p_ess " + str(p_ess) + " with load " + str(p_load) + " and p_ev " + str(p_ev_single)) self.logger.debug("Implemented actions") self.logger.debug("PV generation: " + str(p_pv)) self.logger.debug("Load: " + str(p_load)) self.logger.debug("Grid before: " + str(p_grid)) if not self.single_ev: p_grid = feasible_ev_charging_power - p_pv - p_ess + p_load self.logger.debug("Grid after: " + str(p_grid)) self.logger.debug("ESS discharge: " + str(p_ess)) self.logger.debug("Real EV charging " + str(feasible_ev_charging_power)) stochastic_end_time = time.time() self.logger.debug("Time Information".center(80, "#")) self.logger.debug("") self.logger.debug("Start time: " + str(stochastic_start_time)) self.logger.debug("End time: " + str(stochastic_end_time)) execution_time = stochastic_end_time - stochastic_start_time self.logger.debug("Programming execution time: " + str(execution_time)) self.logger.debug("") self.logger.debug("#" * 80) self.logger.debug("p_fronius_pct_output") p_fronius_pct_output = [] if "Fronius_Max_Power" in data_dict[None].keys(): p_fronius_max_power = data_dict[None][ "Fronius_Max_Power"][None] #self.logger.debug("p_fronius_max_power "+str(p_fronius_max_power)) p_fronius_pct_output_calc = p_ess * 100 / p_fronius_max_power if p_fronius_pct_output_calc < 0: p_fronius_pct_output_calc = 0 elif p_fronius_pct_output_calc > 100: p_fronius_pct_output_calc = 100 p_fronius_pct_output.append(p_fronius_pct_output_calc) self.logger.debug("p_ess_output_pct") p_ess_output_pct = [] if "ESS_Max_Charge_Power" in data_dict[None].keys(): p_ess_max_power = data_dict[None][ "ESS_Max_Charge_Power"][None] #self.logger.debug("p_ess_max_power "+str(p_ess_max_power)) p_ess_output_pct_calc = p_ess * 100 / p_ess_max_power if p_ess_output_pct_calc < -100: p_ess_output_pct_calc = -100 elif p_ess_output_pct_calc > 100: p_ess_output_pct_calc = 100 p_ess_output_pct.append(p_ess_output_pct_calc) self.logger.debug("SoC_output") SoC_output = [] if "SoC_Value" in data_dict[None].keys(): SoC_Value = data_dict[None]["SoC_Value"][None] SoC_output.append(SoC_Value) self.logger.debug("GESSCon_Output") GESSCon_Output = [] if "ESS_Control" in data_dict[None].keys(): GESSCon_Value = data_dict[None]["ESS_Control"][0] GESSCon_Output.append(GESSCon_Value) results = { "id": self.id, "P_PV_Output": p_pv, "P_Grid_Output": p_grid, "P_ESS_Output": p_ess, "P_VAC_Output": p_vac, "feasible_ev_charging_power": feasible_ev_charging_power, "p_ev": p_ev, "execution_time": execution_time, "P_Fronius_Pct_Output": p_fronius_pct_output, "P_ESS_Output_Pct": p_ess_output_pct, "SoC_copy": SoC_output, "Global_control": GESSCon_Output } # update soc self.logger.debug("results " + str(results)) socs = ev_park.charge_ev(p_ev, self.dT_in_seconds, self.single_ev) results_publish = { "P_PV_Output": [p_pv], "P_Grid_Output": [p_grid], "P_ESS_Output": [p_ess], "P_VAC_Output": [p_vac], "feasible_ev_charging_power": [feasible_ev_charging_power], "execution_time": [execution_time], "P_Fronius_Pct_Output": p_fronius_pct_output, "P_ESS_Output_Pct": p_ess_output_pct, "SoC_copy": SoC_output, "Global_control": GESSCon_Output } for key, value in p_ev.items(): ev_id = ev_park.get_hosted_ev(key) if ev_id: results_publish[key + "/p_ev"] = { "bn": "chargers/" + key, "n": ev_id + "/p_ev", "v": [value] } for key, value in socs.items(): ev_id = ev_park.get_hosted_ev(key) if ev_id: results_publish[key + "/SoC"] = { "bn": "chargers/" + key, "n": ev_id + "/SoC", "v": [value] } self.logger.debug("results_publish " + str(results_publish)) self.output.publish_data(self.id, results_publish, self.dT_in_seconds) self.monitor.send_monitor_ping(self.control_frequency) #results.clear() ev_park = None #results_publish.clear() #data_dict.clear() #with open(output_log_filepath, "w") as log_file: #json.dump(results, log_file, indent=4) #jsonDecision = {str(k): v for k, v in Decision.items()} #with open(decision_log_filepath, "w") as log_file: #json.dump(jsonDecision, log_file, indent=4) count += 1 if self.repetition > 0 and count >= self.repetition: self.repetition_completed = True break time_spent = IDStatusManager.update_count( self.repetition, self.id, self.redisDB) final_time_total = time.time() sleep_time = self.control_frequency - int( final_time_total - start_time_total) if sleep_time > 0: self.logger.info( "Optimization thread going to sleep for " + str(sleep_time) + " seconds") for i in range(sleep_time): time.sleep(1) if self.redisDB.get_bool( self.stop_signal_key ): #or self.stopRequest.isSet(): break if self.redisDB.get("End ofw") == "True": break
def optimize(self, count, optsolver, solver_manager, solver_name, model_path): while not self.redisDB.get_bool(self.stop_signal_key) and not self.stopRequest.isSet(): action_handle_map = {} start_time_total = time.time() self.logger.info("waiting for data") data_dict = self.input.get_data(preprocess=True) # blocking call if self.redisDB.get_bool(self.stop_signal_key) or self.stopRequest.isSet(): break ###################################### # STOCHASTIC OPTIMIZATION ev_park = self.input.inputPreprocess.ev_park max_number_of_cars = ev_park.get_num_of_cars() ess_soc_states = self.input.inputPreprocess.ess_soc_states vac_soc_states = self.input.inputPreprocess.vac_soc_states position_states = [0, 1] domain_range = (ev_park.total_charging_stations_power * self.dT_in_seconds) / ( ev_park.get_vac_capacity() * 3600) * 100 ess_max_power = data_dict[None]["ESS_Max_Charge_Power"][None] ess_min_power = data_dict[None]["ESS_Max_Discharge_Power"][None] ess_capacity = data_dict[None]["ESS_Capacity"][None] #self.logger.debug("ess_capacity: "+str(ess_capacity)+" ess_min_power: "+str(ess_min_power)+ " ess_max_power: "+str(ess_max_power)) ess_domain_range_max = math.floor((ess_max_power / ess_capacity) * 100) ess_domain_range_min = math.floor((ess_min_power / ess_capacity) * 100) ess_steps = self.input.inputPreprocess.ess_steps ess_domain_min = - (math.floor(ess_domain_range_min / ess_steps) * ess_steps) ess_domain_max = (math.floor(ess_domain_range_max / ess_steps) * ess_steps) + ess_steps vac_steps = self.input.inputPreprocess.vac_steps vac_domain_min = vac_soc_states[0] vac_domain_max = domain_range + vac_steps # ess_domain_min = ess_steps * round(ess_domain_min / ess_steps) # ess_domain_max = ess_steps * round(ess_domain_max / ess_steps) vac_domain_min = vac_steps * math.floor(vac_domain_min / vac_steps) vac_domain_max = vac_steps * math.floor(vac_domain_max / vac_steps) #self.logger.debug("vac domain : "+str(vac_domain_min)+ " "+ str(vac_domain_max)+ " " + str(vac_steps)) ess_decision_domain = np.arange(ess_domain_min, ess_domain_max, ess_steps).tolist() vac_decision_domain = np.arange(vac_domain_min, vac_domain_max, vac_steps).tolist() vac_decision_domain_n = np.arange(vac_domain_min, vac_domain_max, vac_steps) T = self.horizon_in_steps if self.single_ev: behaviour_model = self.input.inputPreprocess.simulator(time_resolution=self.dT_in_seconds, horizon=self.horizon_in_steps, single_ev=True) # Initialize empty lookup tables keylistforValue = [(t, s_ess, s_vac, s_pos) for t, s_ess, s_vac, s_pos in product(list(range(0, T + 1)), ess_soc_states, vac_soc_states, position_states)] keylistforDecisions = [(t, s_ess, s_vac, s_pos) for t, s_ess, s_vac, s_pos in product(list(range(0, T)), ess_soc_states, vac_soc_states, position_states)] Value = dict.fromkeys(keylistforValue) Decision = dict.fromkeys(keylistforDecisions) for t, s_ess, s_vac, s_pos in product(range(0, T), ess_soc_states, vac_soc_states, position_states): Decision[t, s_ess, s_vac, s_pos] = {'PV': None, 'Grid': None, 'ESS': None, 'VAC': None} Value[t, s_ess, s_vac, s_pos] = None for s_ess, s_vac, s_pos in product(ess_soc_states, vac_soc_states, position_states): Value[T, s_ess, s_vac, s_pos] = 5.0 else: behaviour_model = self.input.inputPreprocess.simulator(time_resolution=self.dT_in_seconds, horizon=self.horizon_in_steps, max_number_of_cars=max_number_of_cars) # Initialize empty lookup tables keylistforValue = [(t, s_ess, s_vac) for t, s_ess, s_vac in product(list(range(0, T + 1)), ess_soc_states, vac_soc_states)] keylistforDecisions = [(t, s_ess, s_vac) for t, s_ess, s_vac in product(list(range(0, T)), ess_soc_states, vac_soc_states)] Value = dict.fromkeys(keylistforValue) Decision = dict.fromkeys(keylistforDecisions) for t, s_ess, s_vac in product(range(0, T), ess_soc_states, vac_soc_states): Decision[t, s_ess, s_vac] = {'PV': None, 'Grid': None, 'ESS': None, 'VAC': None} Value[t, s_ess, s_vac] = None for s_ess, s_vac in product(ess_soc_states, vac_soc_states): Value[T, s_ess, s_vac] = 1.0 # self.logger.debug("Value "+str(Value)) #self.logger.debug("ess_decision_domain " + str(ess_decision_domain)) #self.logger.debug("vac_decision_domain " + str(vac_decision_domain)) #self.logger.debug("ess_soc_states " + str(ess_soc_states)) #self.logger.debug("vac_soc_states " + str(vac_soc_states)) #time_info = datetime.datetime.now().strftime("%Y-%m-%d--%H-%M-%S") #filename = "log-"+str(uuid.uuid1())+"-"+str(time_info)+".json" #input_log_filepath = os.path.join("/usr/src/app/logs", "input-"+str(filename)) #output_log_filepath = os.path.join("/usr/src/app/logs", "output-"+str(filename)) #decision_log_filepath = os.path.join("/usr/src/app/logs", "decision-"+str(filename)) #with open(input_log_filepath, "w") as log_file: #json.dump(data_dict, log_file, indent=4) stochastic_start_time = time.time() min_value = 100 * float(data_dict[None]["ESS_Min_SoC"][None]) max_value = 100 * float(data_dict[None]["ESS_Max_SoC"][None]) max_vac_soc_states = max(vac_soc_states) reverse_steps = reversed(range(0, self.horizon_in_steps)) for timestep in reverse_steps: self.logger.info("Timestep :#"+str(timestep)) instance_id = 0 instance_info = {} if self.single_ev: value_index = [(s_ess, s_vac, s_pos) for t, s_ess, s_vac, s_pos in Value.keys() if t == timestep + 1] value = {v: Value[timestep + 1, v[0], v[1], v[2]] for v in value_index} bm_idx = [(pos, next_pos) for t, pos, next_pos in behaviour_model.keys() if t == timestep] bm = {v: behaviour_model[timestep, v[0], v[1]] for v in bm_idx} ess_vac_product = product(ess_soc_states, vac_soc_states, position_states) else: value_index = [(s_ess, s_vac) for t, s_ess, s_vac in Value.keys() if t == timestep + 1] value = {v: Value[timestep + 1, v[0], v[1]] for v in value_index} bm_idx = behaviour_model[timestep].keys() bm = behaviour_model[timestep] ess_vac_product = product(ess_soc_states, vac_soc_states) data_dict[None]["Value_Index"] = {None: value_index} data_dict[None]["Value"] = value data_dict[None]["Behavior_Model_Index"] = {None: bm_idx} data_dict[None]["Behavior_Model"] = bm data_dict[None]["Timestep"] = {None: timestep} for combination in ess_vac_product: feasible_Pess = [] # Feasible charge powers to ESS under the given conditions if self.single_ev: recharge_value = int(data_dict[None]["Recharge"][None]) ini_ess_soc, ini_vac_soc, position = combination for p_ESS in ess_decision_domain: # When decided charging with p_ESS compare_value = ini_ess_soc - p_ESS # self.logger.debug("min_value "+str(min_value)) # self.logger.debug("max_value " + str(max_value)) if min_value <= compare_value <= max_value: # if the final ess_SoC is within the specified domain feasible_Pess.append(p_ESS) #self.logger.debug("feasible p_ESS " + str(feasible_Pess)) feasible_Pvac = [] # Feasible charge powers to VAC under the given conditions if recharge_value == 1: # When decided charging with p_VAC if vac_decision_domain[0] <= max_vac_soc_states - ini_vac_soc: # if the final vac_SoC is within the specified domain index = np.searchsorted(vac_decision_domain_n, max_vac_soc_states - ini_vac_soc) feasible_Pvac = vac_decision_domain[0:index + 1] else: feasible_Pvac.append(0) # self.logger.debug("feasible p_VAC " + str(feasible_Pvac)) else: ini_ess_soc, ini_vac_soc = combination for p_ESS in ess_decision_domain: # When decided charging with p_ESS compare_value = ini_ess_soc - p_ESS # self.logger.debug("min_value "+str(min_value)) # self.logger.debug("max_value " + str(max_value)) if min_value <= compare_value <= max_value: # if the final ess_SoC is within the specified domain feasible_Pess.append(p_ESS) #self.logger.debug("feasible p_ESS " + str(feasible_Pess)) feasible_Pvac = [] # Feasible charge powers to VAC under the given conditions # When decided charging with p_VAC if vac_decision_domain[0] <= max_vac_soc_states - ini_vac_soc: # if the final vac_SoC is within the specified domain index = np.searchsorted(vac_decision_domain_n, max_vac_soc_states - ini_vac_soc) feasible_Pvac = vac_decision_domain[0:index + 1] # self.logger.debug("feasible p_VAC " + str(feasible_Pvac)) data_dict[None]["Feasible_ESS_Decisions"] = {None: feasible_Pess} data_dict[None]["Feasible_VAC_Decisions"] = {None: feasible_Pvac} data_dict[None]["Initial_ESS_SoC"] = {None: ini_ess_soc} #self.logger.debug("ini_ess_soc "+str(ini_ess_soc)) data_dict[None]["Initial_VAC_SoC"] = {None: ini_vac_soc} #self.logger.debug("ini_vac_soc " + str(ini_vac_soc)) final_ev_soc = ini_vac_soc - data_dict[None]["Unit_Consumption_Assumption"][None] if final_ev_soc < data_dict[None]["VAC_States_Min"][None]: final_ev_soc = data_dict[None]["VAC_States_Min"][None] data_dict[None]["final_ev_soc"] = {None: final_ev_soc} # Creating an optimization instance with the referenced model try: #self.logger.debug("Creating an optimization instance") #self.logger.debug("input data: " + str(data_dict)) instance = self.my_class.model.create_instance(data_dict) except pyutilib.common.ApplicationError: # pragma:nocover self.logger.error("Error creating instance") self.logger.error("Pyutilib error") err = sys.exc_info()[1] self.logger.error(err) #except Exception as e: #self.logger.error("Error creating instance") #self.logger.error(e) # instance = self.my_class.model.create_instance(self.data_path) #self.logger.info("Instance created with pyomo") # * Queue the optimization instance try: #self.logger.info(instance.pprint()) action_handle = solver_manager.queue(instance, opt=optsolver, warmstart=False)#, tee=False, logfile="/usr/src/app/logs/pyomo.log") #self.logger.debug("Solver queue created " + str(action_handle)) #self.logger.debug("solver queue actions = " + str(solver_manager.num_queued())) #action_handle_map[action_handle] = str(self.id) action_handle_map[action_handle] = str(instance_id) #self.logger.debug("Action handle map: " + str(action_handle_map)) # start_time = time.time() # self.logger.debug("Optimization starting time: " + str(start_time)) if self.single_ev: inst = Instance(str(instance_id), ini_ess_soc, ini_vac_soc, position=position, instance=instance) else: inst = Instance(str(instance_id), ini_ess_soc, ini_vac_soc, instance=instance) #instance_info.append(inst) instance_info[instance_id] = inst instance_id += 1 except pyutilib.common.ApplicationError: # pragma:nocover self.logger.error("Error creating queue") self.logger.error("Pyutilib error") err = sys.exc_info()[1] self.logger.error(err) #except Exception as e: #self.logger.error("exception " + str(e)) # * Run the solver # retrieve the solutions for i in range(instance_id): try: this_action_handle = solver_manager.wait_any() result = solver_manager.get_results(this_action_handle) #self.logger.debug("solver queue actions = " + str(solver_manager.num_queued())) solved_name = None if this_action_handle in action_handle_map.keys(): solved_name = action_handle_map.pop(this_action_handle) if solved_name: inst = instance_info[int(solved_name)] #instance_info[int(solved_name)].addResult(result) #result = inst.result ini_ess_soc = inst.ini_ess_soc ini_vac_soc = inst.ini_vac_soc position = inst.position instance = inst.instance if (result.solver.status == SolverStatus.ok) and ( result.solver.termination_condition == TerminationCondition.optimal): # this is feasible and optimal #self.logger.info("Solver status and termination condition ok") #self.logger.debug("Results for " + inst.instance_id + " with id: " + str(self.id)) #self.logger.debug(result) instance.solutions.load_from(result) # * if solved get the values in dict try: my_dict = {} for v in instance.component_objects(Var, active=True): #self.logger.debug("Variable in the optimization: " + str(v)) varobject = getattr(instance, str(v)) var_list = [] try: # Try and add to the dictionary by key ref for index in varobject: var_list.append(varobject[index].value) #self.logger.debug("Identified variables " + str(var_list)) my_dict[str(v)] = var_list except Exception as e: self.logger.error("error reading result "+str(e)) if self.single_ev: combined_key = (timestep, ini_ess_soc, ini_vac_soc, position) else: combined_key = (timestep, ini_ess_soc, ini_vac_soc) Decision[combined_key]['Grid'] = my_dict["P_GRID_OUTPUT"][0] Decision[combined_key]['PV'] = my_dict["P_PV_OUTPUT"][0] Decision[combined_key]['ESS'] = my_dict["P_ESS_OUTPUT"][0] Decision[combined_key]['VAC'] = my_dict["P_VAC_OUTPUT"][0] Value[combined_key] = my_dict["P_PV_OUTPUT"][0] #self.logger.info("Done".center(80, "#")) #self.logger.info("Timestep :#"+str(timestep)+" : "+str(ini_ess_soc)+", "+str(ini_vac_soc)) #self.logger.info("#" * 80) # self.output.publish_data(self.id, my_dict) except Exception as e: self.logger.error("error setting decision or value "+str(e)) elif result.solver.termination_condition == TerminationCondition.infeasible: # do something about it? or exit? self.logger.info("Termination condition is infeasible") else: self.logger.info("Nothing fits") except pyutilib.common.ApplicationError: # pragma:nocover self.logger.error("Pyutilib error") err = sys.exc_info()[1] self.logger.error(err) #solver_manager.queue.clear() del instance_info # erasing files from pyomo folder = "/usr/src/app/logs/pyomo" for the_file in os.listdir(folder): file_path = os.path.join(folder, the_file) try: if os.path.isfile(file_path): os.unlink(file_path) # elif os.path.isdir(file_path): shutil.rmtree(file_path) except Exception as e: self.logger.error(e) #with open("/usr/src/app/optimization/resources/Decision_p.txt", "w") as f: #f.write(str(Decision)) #with open("/usr/src/app/optimization/resources/Value_p.txt", "w") as f: #f.write(str(Value)) #self.logger.info("written to file") #break initial_ess_soc_value = float(data_dict[None]["SoC_Value"][None]) initial_vac_soc_value = float(data_dict[None]["VAC_SoC_Value"][None]) if self.single_ev: recharge_value = int(data_dict[None]["Recharge"][None]) result_key = (0, initial_ess_soc_value, initial_vac_soc_value, recharge_value) else: result_key = (0, initial_ess_soc_value, initial_vac_soc_value) p_pv = Decision[result_key]['PV'] p_grid = Decision[result_key]['Grid'] p_ess = Decision[result_key]['ESS'] p_vac = Decision[result_key]['VAC'] del reverse_steps del Decision del Value del value del value_index del bm_idx del bm del ess_vac_product del ess_decision_domain del vac_decision_domain del vac_decision_domain_n del behaviour_model del keylistforDecisions del keylistforValue p_ev = {} self.logger.debug("Dynamic programming calculations") self.logger.debug("PV generation:" + str(p_pv)) self.logger.debug("Import:" + str(p_grid)) self.logger.debug("ESS discharge:" + str(p_ess)) self.logger.debug("VAC charging" + str(p_vac)) ############################################################################# # This section distributes virtual capacity charging power into the cars plugged chargers in the station # detect which cars are connected to the chargers in the commercial charging station # calculate the maximum feasible charging power input under given SoC dT = data_dict[None]["dT"][None] ESS_Max_Charge = data_dict[None]["ESS_Max_Charge_Power"][None] ESS_Capacity = data_dict[None]["ESS_Capacity"][None] del data_dict connections = ev_park.max_charge_power_calculator(dT) # Calculation of the feasible charging power at the commercial station max_power_for_cars = sum(connections.values()) feasible_ev_charging_power = min(max_power_for_cars, p_vac) self.logger.debug("feasible_ev_charging_power" + str(feasible_ev_charging_power)) self.logger.debug("max_power_for_cars " + str(max_power_for_cars)) for charger, max_charge_power_of_car in connections.items(): if feasible_ev_charging_power == 0: p_ev[charger] = 0 else: power_output_of_charger = feasible_ev_charging_power * ( max_charge_power_of_car / max_power_for_cars) p_ev[charger] = power_output_of_charger # self.logger.debug("power_output_of_charger "+str(power_output_of_charger)+"in charger "+str(charger) ) ############################################################################# ############################################################################# # This section decides what to do with the non utilized virtual capacity charging power """ # Power leftover: Non implemented part of virtual capacity charging power leftover_vac_charging_power = p_vac - feasible_ev_charging_power # Still leftover is attempted to be charged to the ESS ess_charger_limit = ESS_Max_Charge ess_capacity_limit = ((100 - initial_ess_soc_value) / 100) * (ESS_Capacity / dT) max_ess_charging_power = ess_capacity_limit - p_ess#min(ess_charger_limit, ess_capacity_limit, still_leftover) p_ess = p_ess + max_ess_charging_power # Leftover is attempted to be removed with less import less_import = min(p_grid, leftover_vac_charging_power) p_grid = p_grid - less_import # Some part could be still left still_leftover = leftover_vac_charging_power - less_import # Final leftover: if the ESS does not allow charging all leftover, final leftover will be compensated by PV curtailment final_leftover = still_leftover - max_ess_charging_power p_pv = p_pv - final_leftover """ self.logger.debug("Implemented actions") self.logger.debug("PV generation:" + str(p_pv)) self.logger.debug("Import:" + str(p_grid)) self.logger.debug("ESS discharge:" + str(p_ess)) self.logger.debug("Real EV charging" + str(feasible_ev_charging_power)) stochastic_end_time = time.time() self.logger.debug("Time Information".center(80, "#")) self.logger.debug("") self.logger.debug("Start time: "+str(stochastic_start_time)) self.logger.debug("End time: "+str(stochastic_end_time)) execution_time = stochastic_end_time - stochastic_start_time self.logger.debug("Programming execution time: "+str(execution_time)) self.logger.debug("") self.logger.debug("#" * 80) results = { "id": self.id, "p_pv": p_pv, "p_grid": p_grid, "p_ess": p_ess, "p_vac": p_vac, "feasible_ev_charging_power": feasible_ev_charging_power, "p_ev": p_ev, "execution_time": execution_time } # update soc ev_park.charge_ev(p_ev, self.dT_in_seconds) #time.sleep(60) results_publish = { "p_pv": [p_pv], "p_grid": [p_grid], "p_ess": [p_ess], "p_vac": [p_vac], "feasible_ev_charging_power": [feasible_ev_charging_power], "execution_time": [execution_time] } for key, value in p_ev.items(): ev_id = ev_park.get_hosted_ev(key) if ev_id: results_publish[key+"/p_ev"] = {"bn":"chargers/"+key, "n":ev_id+"/p_ev", "v":[value]} self.output.publish_data(self.id, results_publish, self.dT_in_seconds) del results del ev_park del results_publish #with open(output_log_filepath, "w") as log_file: #json.dump(results, log_file, indent=4) #jsonDecision = {str(k): v for k, v in Decision.items()} #with open(decision_log_filepath, "w") as log_file: #json.dump(jsonDecision, log_file, indent=4) count += 1 if self.repetition > 0 and count >= self.repetition: self.repetition_completed = True break self.logger.info("Optimization thread going to sleep for " + str(self.control_frequency) + " seconds") time_spent = IDStatusManager.update_count(self.repetition, self.id, self.redisDB) final_time_total = time.time() sleep_time = self.control_frequency - int(final_time_total - start_time_total) if sleep_time > 0: for i in range(sleep_time): time.sleep(1) if self.redisDB.get_bool(self.stop_signal_key) or self.stopRequest.isSet(): break
def optimize(self, count, solver_name, model_path): self.logger.debug("############## testsf") while not self.redisDB.get_bool( self.stop_signal_key): # and not self.stopRequest.isSet(): start_time_total = time.time() self.logger.debug("number of workers = " + str(self.number_of_workers)) self.logger.info("waiting for data") data_dict = self.input.get_data(preprocess=True) # blocking call if self.redisDB.get_bool( self.stop_signal_key): # or self.stopRequest.isSet(): break ###################################### # STOCHASTIC OPTIMIZATION ev_park = self.input.inputPreprocess.ev_park max_number_of_cars = ev_park.get_num_of_cars() position_states = [0, 1] domain_range = (ev_park.total_charging_stations_power * self.dT_in_seconds) / (ev_park.get_vac_capacity() * 3600) * 100 vac_soc_states, vac_decision_domain, vac_decision_domain_n = self.calculate_vac_domain( domain_range) ess_soc_states, ess_decision_domain = self.calculate_ess_domain( data_dict, domain_range) T = self.horizon_in_steps behaviour_model, Value, Decision = self.get_values( T, ess_soc_states, vac_soc_states, position_states, max_number_of_cars) stochastic_start_time = time.time() min_value = 100 * float(data_dict[None]["ESS_Min_SoC"][None]) max_value = 100 * float(data_dict[None]["ESS_Max_SoC"][None]) max_vac_soc_states = max(vac_soc_states) reverse_steps = reversed(range(0, self.horizon_in_steps)) for timestep in reverse_steps: if self.redisDB.get_bool(self.stop_signal_key): break else: self.logger.info("Timestep :#" + str(timestep)) value_index, value, bm_idx, bm, ess_vac_product = self.calculate_internal_values( timestep, Value, behaviour_model, ess_soc_states, vac_soc_states, position_states) data_dict[None]["Value_Index"] = {None: value_index} data_dict[None]["Value"] = value data_dict[None]["Behavior_Model_Index"] = {None: bm_idx} data_dict[None]["Behavior_Model"] = bm data_dict[None]["Timestep"] = {None: timestep} # retrieve the solutions try: futures = [] with concurrent.futures.ProcessPoolExecutor( max_workers=self.number_of_workers ) as executor: if self.single_ev: for combination in ess_vac_product: ini_ess_soc, ini_vac_soc, position = combination futures.append( executor.submit( OptControllerStochastic. create_instance_and_solve, data_dict, ess_decision_domain, min_value, max_value, vac_decision_domain, vac_decision_domain_n, max_vac_soc_states, timestep, True, solver_name, model_path, ini_ess_soc, ini_vac_soc, position)) else: for combination in ess_vac_product: ini_ess_soc, ini_vac_soc = combination futures.append( executor.submit( OptControllerStochastic. create_instance_and_solve, data_dict, ess_decision_domain, min_value, max_value, vac_decision_domain, vac_decision_domain_n, max_vac_soc_states, timestep, False, solver_name, model_path, ini_ess_soc, ini_vac_soc)) for future in concurrent.futures.as_completed( futures): try: d, v = future.result() Value.update(v) Decision.update(d) except Exception as exc: self.logger.error("caused an exception: " + str(exc)) except Exception as e: self.logger.error(e) value_index.clear() value.clear() bm.clear() # erasing files from pyomo folder = "/usr/src/app/logs/pyomo_" + str(self.id) self.erase_pyomo_files(folder) """ with open("/usr/src/app/optimization/resources/Value_p.txt", "w") as f: f.write(str(Value)) self.logger.info("written to file") """ if self.redisDB.get_bool(self.stop_signal_key): break else: initial_ess_soc_value = float( data_dict[None]["SoC_Value"][None]) self.logger.debug("initial_ess_soc_value " + str(initial_ess_soc_value)) initial_vac_soc_value = float( data_dict[None]["VAC_SoC_Value"][None]) self.logger.debug("initial_vac_soc_value " + str(initial_vac_soc_value)) if self.single_ev: recharge_value = int(data_dict[None]["Recharge"][None]) result_key = (0, initial_ess_soc_value, initial_vac_soc_value, recharge_value) else: result_key = (0, initial_ess_soc_value, initial_vac_soc_value) p_pv = Decision[result_key]['PV'] p_grid = Decision[result_key]['Grid'] p_ess = Decision[result_key]['ESS'] p_vac = Decision[result_key]['VAC'] Decision.clear() Value.clear() p_ev = {} self.logger.debug("Dynamic programming calculations") self.logger.debug("PV generation:" + str(p_pv)) self.logger.debug("Import:" + str(p_grid)) self.logger.debug("ESS discharge:" + str(p_ess)) self.logger.debug("VAC charging" + str(p_vac)) ############################################################################# # This section distributes virtual capacity charging power into the cars plugged chargers in the station # detect which cars are connected to the chargers in the commercial charging station # calculate the maximum feasible charging power input under given SoC dT = data_dict[None]["dT"][None] ESS_Max_Charge = data_dict[None]["ESS_Max_Charge_Power"][None] ESS_Capacity = data_dict[None]["ESS_Capacity"][None] data_dict.clear() connections = ev_park.max_charge_power_calculator(dT) # Calculation of the feasible charging power at the commercial station max_power_for_cars = sum(connections.values()) feasible_ev_charging_power = min(max_power_for_cars, p_vac) self.logger.debug("feasible_ev_charging_power" + str(feasible_ev_charging_power)) self.logger.debug("max_power_for_cars " + str(max_power_for_cars)) for charger, max_charge_power_of_car in connections.items(): if feasible_ev_charging_power == 0: p_ev[charger] = 0 else: power_output_of_charger = feasible_ev_charging_power * ( max_charge_power_of_car / max_power_for_cars) p_ev[charger] = power_output_of_charger # self.logger.debug("power_output_of_charger "+str(power_output_of_charger)+"in charger "+str(charger) ) ############################################################################# ############################################################################# # This section decides what to do with the non utilized virtual capacity charging power self.logger.debug("Implemented actions") self.logger.debug("PV generation:" + str(p_pv)) self.logger.debug("Grid before:" + str(p_grid)) p_grid = feasible_ev_charging_power - p_pv - p_ess self.logger.debug("Grid after:" + str(p_grid)) self.logger.debug("ESS discharge:" + str(p_ess)) self.logger.debug("Real EV charging" + str(feasible_ev_charging_power)) stochastic_end_time = time.time() self.logger.debug("Time Information".center(80, "#")) self.logger.debug("") self.logger.debug("Start time: " + str(stochastic_start_time)) self.logger.debug("End time: " + str(stochastic_end_time)) execution_time = stochastic_end_time - stochastic_start_time self.logger.debug("Programming execution time: " + str(execution_time)) self.logger.debug("") self.logger.debug("#" * 80) results = { "id": self.id, "p_pv": p_pv, "p_grid": p_grid, "p_ess": p_ess, "p_vac": p_vac, "feasible_ev_charging_power": feasible_ev_charging_power, "p_ev": p_ev, "execution_time": execution_time } # update soc socs = ev_park.charge_ev(p_ev, self.dT_in_seconds) #time.sleep(60) results_publish = { "p_pv": [p_pv], "p_grid": [p_grid], "p_ess": [p_ess], "p_vac": [p_vac], "feasible_ev_charging_power": [feasible_ev_charging_power], "execution_time": [execution_time] } for key, value in p_ev.items(): ev_id = ev_park.get_hosted_ev(key) if ev_id: results_publish[key + "/p_ev"] = { "bn": "chargers/" + key, "n": ev_id + "/p_ev", "v": [value] } for key, value in socs.items(): ev_id = ev_park.get_hosted_ev(key) if ev_id: results_publish[key + "/SoC"] = { "bn": "chargers/" + key, "n": ev_id + "/SoC", "v": [value] } self.output.publish_data(self.id, results_publish, self.dT_in_seconds) results.clear() ev_park = None results_publish.clear() #with open(output_log_filepath, "w") as log_file: #json.dump(results, log_file, indent=4) #jsonDecision = {str(k): v for k, v in Decision.items()} #with open(decision_log_filepath, "w") as log_file: #json.dump(jsonDecision, log_file, indent=4) count += 1 if self.repetition > 0 and count >= self.repetition: self.repetition_completed = True break time_spent = IDStatusManager.update_count( self.repetition, self.id, self.redisDB) final_time_total = time.time() sleep_time = self.control_frequency - int(final_time_total - start_time_total) if sleep_time > 0: self.logger.info( "Optimization thread going to sleep for " + str(sleep_time) + " seconds") for i in range(sleep_time): time.sleep(1) if self.redisDB.get_bool( self.stop_signal_key ): #or self.stopRequest.isSet(): break
def start(self, id, json_object, dict_object=None): logger.debug(str(json_object)) if json_object is not None: self.model_name = json_object.model_name self.control_frequency = json_object.control_frequency self.horizon_in_steps = json_object.horizon_in_steps self.dT_in_seconds = json_object.d_t_in_seconds self.repetition = json_object.repetition self.solver = json_object.solver self.optimization_type = json_object.optimization_type self.single_ev = json_object.single_ev elif dict_object is not None: self.model_name = dict_object["model"] self.control_frequency = dict_object["control_frequency"] self.horizon_in_steps = dict_object["horizon_in_steps"] self.dT_in_seconds = dict_object["dT_in_seconds"] self.repetition = dict_object["repetition"] self.solver = dict_object["solver"] self.optimization_type = dict_object["optimization_type"] self.single_ev = dict_object["single_ev"] self.set( id, ThreadFactory(self.model_name, self.control_frequency, self.horizon_in_steps, self.dT_in_seconds, self.repetition, self.solver, id, self.optimization_type, self.single_ev)) logger.info("Thread: " + str(self.get(id))) self.redisDB.set("run:" + id, "starting") msg = self.get(id).startOptControllerThread() logger.debug("Answer from Thread factory" + str(msg)) if msg == 0: self.set_isRunning(id, True) logger.debug("Flag isRunning set to True") self.statusThread[id] = threading.Thread(target=self.run_status, args=(id, )) logger.debug("Status of the Thread started") self.statusThread[id].start() meta_data = { "id": id, "model": self.model_name, "control_frequency": self.control_frequency, "horizon_in_steps": self.horizon_in_steps, "dT_in_seconds": self.dT_in_seconds, "repetition": self.repetition, "solver": self.solver, "optimization_type": self.optimization_type, "single_ev": self.single_ev, "ztarttime": time.time() } self.redisDB.set("run:" + id, "running") IDStatusManager.persist_id(id, True, meta_data, self.redisDB) logger.info("running status " + str(self.running)) logger.debug("Command controller start finished") return 0 else: self.set_isRunning(id, False) logger.debug("Flag isRunning set to False") IDStatusManager.persist_id(id, False, None, self.redisDB) self.factory[id].stopOptControllerThread() self.redisDB.set("run:" + id, "stopped") logger.error("Command controller start could not be finished") # logger.debug("System stopped succesfully") return 1