import numpy as np class DG: """simulate a simple diesel generator""" def __init__(self, parameters): self.current_output = None self.name = parameters.keys() self.a_factor = parameters['a'] self.b_factor = parameters['b'] self.c_factor = parameters['c'] self.power_output_max = parameters['power_output_max'] self.power_output_min = parameters['power_output_min'] self.ramping_up = parameters['ramping_up'] self.ramping_down = parameters['ramping_down'] self.last_step_output = None def step(self, action_gen): output_change = action_gen * self.ramping_up # constrain the output_change with ramping up boundary output = self.current_output + output_change if output > 0: output = max(self.power_output_min, min(self.power_output_max, output)) # meet the constraint else: output = 0 self.current_output = output def get_cost(self, output): if output <= 0: cost = 0 else: cost = (self.a_factor * pow(output, 2) + self.b_factor * output + self.c_factor) return cost def reset(self): self.current_output = 0 class Battery: """simulate a simple battery""" def __init__(self, parameters): self.current_capacity = None self.energy_change = None self.capacity = parameters['capacity'] self.max_soc = parameters['max_soc'] self.initial_capacity = parameters['initial_capacity'] self.min_soc = parameters['min_soc'] self.degradation = parameters['degradation'] # degradation cost 1.2 self.max_charge = parameters['max_charge'] # max charge ability self.max_discharge = parameters['max_discharge'] self.efficiency = parameters['efficiency'] def step(self, action_battery): energy = action_battery * self.max_charge updated_capacity = max(self.min_soc, min(self.max_soc, (self.current_capacity * self.capacity + energy) / self.capacity)) # if charge, positive, if discharge, negative self.energy_change = (updated_capacity - self.current_capacity) * self.capacity self.current_capacity = updated_capacity # update capacity to current codition def get_cost(self, energy): # cost depends on the energy change cost = energy ** 2 * self.degradation return cost def SOC(self): return self.current_capacity def reset(self): self.current_capacity = np.random.uniform(0.2, 0.8) class Solar: def __init__(self, parameters): self.current_power = None self.base_voltage = parameters['V_b'] self.sc_current = parameters['I_sc0'] self.oc_voltage = parameters['V_oc0'] self.s_resistance = parameters['R_s'] self.sh_resistance = parameters['R_sh'] self.temper_coefficient = parameters['T_c'] self.opex_cofficient = parameters['O_c'] self.refer_irradiance = parameters['I_ref'] self.refer_temperature = parameters['T_ref'] def step(self, temperature, irradiance, action_voltage=0): I_sc = self.sc_current * (irradiance / self.refer_irradiance) V_oc = self.oc_voltage + self.temper_coefficient * (temperature - self.refer_temperature) current = I_sc - (V_oc / self.sh_resistance) # current = I_sc # for _ in range(10): # 迭代次数 # new_current = I_sc - (V_oc + current * self.s_resistance) / self.sh_resistance # if abs(new_current - current) < 1e-6: # 收敛条件 # break # current = new_current self.current_power = max((1 + action_voltage) * self.base_voltage * current, 0) return self.current_power def get_cost(self, current_power): cost = current_power * self.opex_cofficient return cost def reset(self): self.current_power = 0 class Wind: def __init__(self, parameters): self.current_power = None self.cutin_speed = parameters['cutin_speed'] self.cutout_speed = parameters['cutout_speed'] self.rated_speed = parameters['rated_speed'] self.air_density = parameters['air_density'] self.rotor_radius = parameters['rotor_radius'] self.power_coefficient = parameters['power_coefficient'] self.generator_efficiency = parameters['generator_efficiency'] self.opex_cofficient = parameters['opex_cofficient'] def step(self, wind_speed): if self.cutin_speed <= wind_speed < self.rated_speed: self.current_power = (0.5 * self.air_density * self.rotor_radius ** 2 * wind_speed ** 3 * self.power_coefficient * self.generator_efficiency) / 1e3 elif self.rated_speed <= wind_speed < self.cutout_speed: self.current_power = (0.5 * self.air_density * self.rotor_radius ** 2 * self.rated_speed ** 3 * self.power_coefficient * self.generator_efficiency) / 1e3 else: self.current_power = 0 return self.current_power def gen_cost(self, current_power): cost = current_power * self.opex_cofficient return cost def reset(self): self.current_power = 0 class Grid: def __init__(self): self.on = True self.delta = 1 if self.on: self.exchange_ability = 100 else: self.exchange_ability = 0 def get_cost(self, current_price, energy_exchange): return current_price * energy_exchange * self.delta def retrieve_past_price(self): result = [] # 过去24小时的价格起始、结束索引 start_index = max(0, 24 * (self.day - 1) + self.time - 24) end_index = 24 * (self.day - 1) + self.time past_price = self.price[start_index:end_index] result.extend(past_price) # current_day_price = self.price[24 * self.day:24 * self.day + self.time] # result.extend(current_day_price) return result # def retrive_past_price(self): # result = [] # if self.day < 1: # past_price = self.past_price # else: # past_price = self.price[24 * (self.day - 1):24 * self.day] # for item in past_price[(self.time - 24)::]: # result.append(item) # for item in self.price[24 * self.day:(24 * self.day + self.time)]: # result.append(item) # return result