wgz_decision/models/env.py

140 lines
5.7 KiB
Python
Raw Normal View History

2025-02-11 14:38:52 +08:00
import gym
import pandas as pd
from data_manager import *
from module import *
from parameters import *
class WgzGym(gym.Env):
def __init__(self, **kwargs):
super(WgzGym, self).__init__()
self.unbalance = None
2025-02-11 19:12:33 +08:00
self.reward = None
2025-02-11 14:38:52 +08:00
self.current_output = None
self.final_step_outputs = None
self.data_manager = DataManager()
self._load_year_data()
self.month = 1
self.day = 1
self.TRAIN = True
self.current_time = None
self.episode_length = 24
self.penalty_coefficient = 50 # 约束惩罚系数
2025-02-11 19:12:33 +08:00
self.sell_coefficient = 0.5 # 售出利润系数
2025-02-13 14:06:41 +08:00
self.a = 0.5
self.b = 0.3
self.c = 0.2
2025-02-13 15:05:12 +08:00
self.heat_a = 0.6
self.power_a = 0.4
2025-02-11 14:38:52 +08:00
self.EC_parameters = kwargs.get('EC_parameters', EC_parameters) # 电解水制氢器
self.HST_parameters = kwargs.get('dg_parameters', dg_parameters) # 储氢罐
self.grid = Grid()
self.EC = EC(self.EC_parameters)
self.HST = HST(self.HST_parameters)
self.action_space = gym.spaces.Box(low=-1, high=1, shape=(3,), dtype=np.float32)
'''
时间 光伏 温度湿度暂未考虑 电需 热需转化为对应热水所需瓦数 人数 电价 7
2025-02-11 19:12:33 +08:00
电解水制氢功率 储氢罐容量占比 市电功率注意标准化 3
2025-02-11 14:38:52 +08:00
'''
self.state_space = gym.spaces.Box(low=0, high=1, shape=(10,), dtype=np.float32)
def reset(self, *args):
self.month = np.random.randint(1, 13) # choose 12 month
if self.TRAIN:
self.day = np.random.randint(1, 20)
else:
self.day = np.random.randint(20, Constant.MONTHS_LEN[self.month - 1])
self.current_time = 0
self.EC.reset()
self.HST.reset()
return self._build_state()
def _build_state(self):
2025-02-11 19:12:33 +08:00
hst_soc = self.HST.current_soc
ec_out = self.EC.get_hydrogen()
2025-02-13 15:05:12 +08:00
grid_ex = self.grid
2025-02-11 14:38:52 +08:00
time_step = self.current_time
price = self.data_manager.get_price_data(self.month, self.day, self.current_time)
temper = self.data_manager.get_temperature_data(self.month, self.day, self.current_time)
solar = self.data_manager.get_solar_data(self.month, self.day, self.current_time)
load = self.data_manager.get_load_data(self.month, self.day, self.current_time)
heat = self.data_manager.get_heat_data(self.month, self.day, self.current_time)
people = self.data_manager.get_people_data(self.month, self.day, self.current_time)
2025-02-11 19:12:33 +08:00
obs = np.concatenate((np.float32(time_step), np.float32(price), np.float32(temper),
np.float32(solar), np.float32(load), np.float32(heat),
2025-02-13 15:05:12 +08:00
np.float32(people), np.float32(ec_out), np.float32(hst_soc), np.float32(grid_ex)), axis=None)
2025-02-11 14:38:52 +08:00
return obs
2025-02-11 19:12:33 +08:00
def step(self, action):
2025-02-13 15:05:12 +08:00
# 每个组件执行动作 one step
2025-02-11 14:38:52 +08:00
current_obs = self._build_state()
2025-02-13 15:05:12 +08:00
self.EC.step(action[0])
2025-02-11 19:12:33 +08:00
self.HST.step(action[1])
2025-02-13 14:06:41 +08:00
self.grid.step(action[2])
2025-02-11 14:38:52 +08:00
price = current_obs[1]
2025-02-11 19:12:33 +08:00
temper = current_obs[2]
solar = current_obs[3]
load = current_obs[4]
heat = current_obs[5]
2025-02-13 15:05:12 +08:00
2025-02-13 14:06:41 +08:00
gym_to_grid = solar + self.HST.get_power() - self.EC.current_power - load
2025-02-13 15:05:12 +08:00
heat_penalty = 0
2025-02-11 14:38:52 +08:00
# reward = 0.0
sell_benefit, buy_cost = 0, 0
2025-02-13 15:05:12 +08:00
# power_penalty = 0
2025-02-11 19:12:33 +08:00
if gym_to_grid >= 0: # 过剩
sell_benefit = self.grid.get_cost(price, gym_to_grid) * self.sell_coefficient
else: # 缺少
buy_cost = self.grid.get_cost(price, abs(gym_to_grid))
2025-02-13 15:05:12 +08:00
power_penalty = abs(gym_to_grid) * self.penalty_coefficient
2025-02-11 14:38:52 +08:00
2025-02-11 19:12:33 +08:00
hst_cost = self.HST.get_cost()
ec_cost = self.EC.get_cost(price)
solar_cost = solar # 待补充
2025-02-13 14:06:41 +08:00
economic_cost = hst_cost + ec_cost + solar_cost - sell_benefit + buy_cost
2025-02-13 15:05:12 +08:00
demand_cost = self.heat_a * heat_penalty + self.power_a * power_penalty
2025-02-13 14:06:41 +08:00
eco_benifit = 0
2025-02-13 15:05:12 +08:00
reward = - self.a * demand_cost - self.b * economic_cost + self.c * eco_benifit
2025-02-11 19:12:33 +08:00
self.unbalance = gym_to_grid
final_step_outputs = [self.HST.current_soc, self.EC.current_power, self.grid.current_power]
2025-02-11 14:38:52 +08:00
self.current_time += 1
finish = (self.current_time == self.episode_length)
if finish:
self.final_step_outputs = final_step_outputs
self.current_time = 0
next_obs = self.reset()
else:
next_obs = self._build_state()
return current_obs, next_obs, float(reward), finish
def _load_year_data(self):
data_df = pd.read_csv('data/all_data.csv', sep=',')
solar = data_df['solar_power'].to_numpy(dtype=float)
temper = data_df['temper'].to_numpy(dtype=float)
energy = data_df['energy_demand'].to_numpy(dtype=float)
water = data_df['water_demand'].to_numpy(dtype=float)
people = data_df['people_count'].to_numpy(dtype=float)
price = data_df['price'].to_numpy(dtype=float)
'''可根据需求重新设计训练数据大小'''
def process_elements(elements, transform_function, add_function):
for e in elements:
transformed_e = transform_function(e)
add_function(transformed_e)
process_elements(solar, lambda x: x, self.data_manager.add_load_element)
process_elements(temper, lambda x: x, self.data_manager.add_load_element)
process_elements(energy, lambda x: x, self.data_manager.add_irradiance_element)
process_elements(water, lambda x: x, self.data_manager.add_temperature_element)
process_elements(people, lambda x: x, self.data_manager.add_wind_element)
process_elements(price, lambda x: x, self.data_manager.add_price_element)