コード例 #1
0
 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)
コード例 #2
0
    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)
コード例 #3
0
 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))
コード例 #4
0
 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))
コード例 #5
0
 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)
コード例 #6
0
 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")
コード例 #7
0
    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
コード例 #8
0
    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
コード例 #10
0
    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
コード例 #11
0
    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
コード例 #12
0
    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