building-agents/module.py

168 lines
6.1 KiB
Python
Raw Normal View History

2024-06-18 10:49:43 +08:00
import numpy as np
class DG:
2024-06-25 14:18:29 +08:00
"""simulate a diesel generator"""
2024-06-18 10:49:43 +08:00
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:
2024-06-25 14:18:29 +08:00
"""simulate a battery"""
2024-06-18 10:49:43 +08:00
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
2024-06-26 15:44:30 +08:00
updated_capacity = np.maximum(self.min_soc,
np.minimum(self.max_soc,
(self.current_capacity * self.capacity + energy) / self.capacity))
2024-06-18 10:49:43 +08:00
# 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:
2024-06-25 14:18:29 +08:00
"""simulate a solar panel"""
2024-06-26 15:44:30 +08:00
2024-06-18 10:49:43 +08:00
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']
2024-06-19 19:38:31 +08:00
self.temper_coefficient = parameters['T_c']
self.opex_cofficient = parameters['O_c']
self.refer_irradiance = parameters['I_ref']
2024-06-18 10:49:43 +08:00
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:
2024-06-25 14:18:29 +08:00
"""simulate a wind turbine"""
2024-06-26 15:44:30 +08:00
2024-06-18 10:49:43 +08:00
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:
2024-06-25 14:18:29 +08:00
"""simulate a grid"""
2024-06-26 15:44:30 +08:00
2024-06-18 10:49:43 +08:00
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