diff --git a/docs/source/pages/environments.rst b/docs/source/pages/environments.rst index 458f00ded4..2ca6507709 100644 --- a/docs/source/pages/environments.rst +++ b/docs/source/pages/environments.rst @@ -228,6 +228,12 @@ This allows for a **dynamic definition** of these spaces. Let's see the fields r `variables `__ folder of the project (*RDD* file). + .. note:: In case a new observation variable is added to the default ones for an environment, care must be + taken in case normalization is to be done. This is because you have to update + the dictionary of ranges of values available in `constants.py `__ as discussed in + issue `#249 `__. You can use the range_getter function of `common.py `__ to get these + ranges automatically from a experiment output folder. + - **observation_space**: Definition of the observation space following the **OpenAI gym standard**. This space is used to represent all the observations variables that we have previously defined. Remember that the **year, month, day and hour** are added by *Sinergym* later, diff --git a/docs/source/pages/wrappers.rst b/docs/source/pages/wrappers.rst index 1d2f62dd03..0c0455d80d 100644 --- a/docs/source/pages/wrappers.rst +++ b/docs/source/pages/wrappers.rst @@ -45,4 +45,8 @@ An usage of these wrappers could be the next: .. warning:: The order of wrappers if you are going to use several at the same time is really important. The correct order is **Normalization - Logger - MultiObs** and subsets (for example, *Normalization* - *Multiobs* is valid). +.. warning:: If you add new observation variables to the environment than the default ones, you have + to update the **value range dictionary** in `sinergym/sinergym/utils/constants.py `__ + so that normalization can be applied correctly. Otherwise, you will encounter bug `#249 `__. + .. note:: For more information about *Sinergym* Logger, visit :ref:`Logger`. \ No newline at end of file diff --git a/sinergym/utils/common.py b/sinergym/utils/common.py index 7adc111572..0fce25b4b3 100644 --- a/sinergym/utils/common.py +++ b/sinergym/utils/common.py @@ -193,7 +193,7 @@ def ranges_getter(output_path: str, """Given a path with simulations outputs, this function is used to extract max and min absolute values of all episodes in each variable. If a dict ranges is given, will be updated. Args: - output_path (str): path with simulations directories (Eplus-env-). + output_path (str): Path with simulation output (Eplus-env-). last_result (Optional[Dict[str, List[float]]], optional): Last ranges dict to be updated. This will be created if it is not given. Returns: @@ -207,33 +207,31 @@ def ranges_getter(output_path: str, result = {} content = os.listdir(output_path) - for simulation in content: + for episode_path in content: if os.path.isdir( output_path + '/' + - simulation) and simulation.startswith('Eplus-env'): - simulation_content = os.listdir(output_path + '/' + simulation) - for episode_dir in simulation_content: - if os.path.isdir( - output_path + - '/' + - simulation + - '/' + - episode_dir): - monitor_path = output_path + '/' + simulation + '/' + episode_dir + '/monitor.csv' - print('Reading ' + monitor_path + ' limits.') - data = pd.read_csv(monitor_path) - - if len(result) == 0: - for column in data: - # variable : [min,max] - result[column] = [np.inf, -np.inf] - + episode_path) and episode_path.startswith('Eplus-env'): + simulation_content = os.listdir(output_path + '/' + episode_path) + + if os.path.isdir( + output_path + + '/' + + episode_path): + monitor_path = output_path + '/' + episode_path + '/monitor.csv' + print('Reading ' + monitor_path + ' limits.') + data = pd.read_csv(monitor_path) + + if len(result) == 0: for column in data: - if np.min(data[column]) < result[column][0]: - result[column][0] = np.min(data[column]) - if np.max(data[column]) > result[column][1]: - result[column][1] = np.max(data[column]) + # variable : [min,max] + result[column] = [np.inf, -np.inf] + + for column in data: + if np.min(data[column]) < result[column][0]: + result[column][0] = np.min(data[column]) + if np.max(data[column]) > result[column][1]: + result[column][1] = np.max(data[column]) return result diff --git a/sinergym/utils/constants.py b/sinergym/utils/constants.py index b7c3b8e016..bffe891985 100644 --- a/sinergym/utils/constants.py +++ b/sinergym/utils/constants.py @@ -58,26 +58,6 @@ 'timestep': [0, 35040], 'total_power_no_units': [-3.259557259261767, -0.0173658369273838]} -RANGES_IW = { - "Site Outdoor Air Drybulb Temperature": [-13.0, 26.0], - "Site Outdoor Air Relative Humidity": [0.0, 100.0], - "Site Wind Speed": [0.0, 11.0], - "Site Wind Direction": [0.0, 360.0], - "Site Diffuse Solar Radiation Rate per Area": [0.0, 378.0], - "Site Direct Solar Radiation Rate per Area": [0.0, 1000.0], - "IW Hot Water System OA Enable Flag OA Setpoint": [-30.0, 30.0], - "IW Average PPD": [0.0, 100.0], - "IW Effective Zone Air Temperature Setpoint": [18.0, 25.0], - "IW North Zone Average Temperature": [18.0, 25.0], - "IW Effective IAT Setpoint by Logics": [18.0, 25.0], - "IW Occupy Mode Flag": [0.0, 1.0], - "IW Calculated Heating Demand": [0.0, 85.0], - 'day': [1.0, 31.0], - 'done': [False, True], - 'hour': [0.0, 23.0], - 'month': [1.0, 12.0], - 'year': [1.0, 2022.0], -} RANGES_DATACENTER = { 'East-ClgSetP-RL': [21.0, 30.0], @@ -124,6 +104,91 @@ 'timestep': [0, 35040] } +RANGES_OFFICE = { + 'Facility Total HVAC Electricity Demand Rate(Whole Building)': [168.34105, + 126668.15], + 'Office_Cooling_RL': [22.500004, 29.99999], + 'Office_Heating_RL': [15.000012, 22.499994], + 'Site Outdoor Air Drybulb Temperature(Environment)': [-1.1, 42.0], + 'Zone Air Temperature(Core_bottom)': [20.70919, 27.480345], + 'Zone Air Temperature(Core_mid)': [21.514507, 26.98882], + 'Zone Air Temperature(Core_top)': [20.49858, 27.10577], + 'Zone Air Temperature(FirstFloor_Plenum)': [20.968946, 27.27035], + 'Zone Air Temperature(MidFloor_Plenum)': [21.107718, 27.317183], + 'Zone Air Temperature(Perimeter_bot_ZN_1)': [15.171554, 30.35336], + 'Zone Air Temperature(Perimeter_bot_ZN_2)': [18.939316, 30.110523], + 'Zone Air Temperature(Perimeter_bot_ZN_3)': [19.154911, 27.721031], + 'Zone Air Temperature(Perimeter_bot_ZN_4)': [18.955957, 31.069431], + 'Zone Air Temperature(Perimeter_mid_ZN_1)': [19.942469, 31.205746], + 'Zone Air Temperature(Perimeter_mid_ZN_2)': [19.25707, 30.427061], + 'Zone Air Temperature(Perimeter_mid_ZN_3)': [19.493652, 28.486017], + 'Zone Air Temperature(Perimeter_mid_ZN_4)': [19.37576, 31.639992], + 'Zone Air Temperature(Perimeter_top_ZN_1)': [19.346384, 31.139534], + 'Zone Air Temperature(Perimeter_top_ZN_2)': [18.630365, 30.676693], + 'Zone Air Temperature(Perimeter_top_ZN_3)': [18.760962, 29.120058], + 'Zone Air Temperature(Perimeter_top_ZN_4)': [18.678907, 32.390034], + 'Zone Air Temperature(TopFloor_Plenum)': [18.011152, 30.430445], + 'Zone Thermostat Cooling Setpoint Temperature(Core_bottom)': [22.500004, + 29.99999], + 'Zone Thermostat Heating Setpoint Temperature(Core_bottom)': [15.000012, + 22.499994], + 'abs_comfort': [0.0, 25.367293089923947], + 'comfort_penalty': [-25.367293089923947, -0.0], + 'day': [1.0, 31.0], + 'done': [False, True], + 'hour': [0.0, 23.0], + 'month': [1.0, 12.0], + 'power_penalty': [-12.66681481600682, -0.0168341048642297], + 'reward': [-12.69354202988205, -0.0084170524321148], + 'time (seconds)': [0, 31536000], + 'timestep': [0, 35040], + 'year': [1991.0, 1992.0] +} + +RANGES_WAREHOUSE = { + 'BulkStorage_Heating_RL': [15.000002, 22.499958], + 'Facility Total HVAC Electricity Demand Rate(Whole Building)': [481.0, + 12384.411], + 'FineStorage_Cooling_RL': [22.500015, 29.999979], + 'FineStorage_Heating_RL': [15.000049, 22.499994], + 'Office_Cooling_RL': [22.500008, 29.999989], + 'Office_Heating_RL': [15.000006, 22.49995], + 'Site Diffuse Solar Radiation Rate per Area(Environment)': [0.0, 588.0], + 'Site Direct Solar Radiation Rate per Area(Environment)': [0.0, 1033.0], + 'Site Outdoor Air Drybulb Temperature(Environment)': [-1.1, 42.0], + 'Site Outdoor Air Relative Humidity(Environment)': [3.0, 100.0], + 'Site Wind Direction(Environment)': [0.0, 357.5], + 'Site Wind Speed(Environment)': [0.0, 13.9], + 'Zone Air Relative Humidity(Zone1 Office)': [6.253238, 100.0], + 'Zone Air Relative Humidity(Zone2 Fine Storage)': [4.621931, 100.0], + 'Zone Air Relative Humidity(Zone3 Bulk Storage)': [6.0304756, 95.72191], + 'Zone Air Temperature(Zone1 Office)': [15.067171, 29.446217], + 'Zone Air Temperature(Zone2 Fine Storage)': [13.976028, 29.089006], + 'Zone Air Temperature(Zone3 Bulk Storage)': [15.5426655, 34.394325], + 'Zone People Occupant Count(Zone1 Office)': [0.0, 5.0], + 'Zone Thermostat Cooling Setpoint Temperature(Zone1 Office)': [22.500008, + 29.999989], + 'Zone Thermostat Cooling Setpoint Temperature(Zone2 Fine Storage)': [22.500015, + 29.999979], + 'Zone Thermostat Heating Setpoint Temperature(Zone1 Office)': [15.000006, + 22.49995], + 'Zone Thermostat Heating Setpoint Temperature(Zone2 Fine Storage)': [15.000049, + 22.499994], + 'Zone Thermostat Heating Setpoint Temperature(Zone3 Bulk Storage)': [15.000002, + 22.499958], + 'abs_comfort': [0.0, 9.527248547862186], + 'comfort_penalty': [-9.527248547862186, -0.0], + 'day': [1.0, 31.0], + 'done': [False, True], + 'hour': [0.0, 23.0], + 'month': [1.0, 12.0], + 'power_penalty': [-1.2384410833362391, -0.0480999999999999], + 'reward': [-5.245662269856689, -0.0240499999999999], + 'time (seconds)': [0, 31536000], + 'timestep': [0, 35040], + 'year': [1991.0, 1992.0] +} + # ---------------------------------------------------------------------------- # # Default Eplus Environments values # # ---------------------------------------------------------------------------- # @@ -213,8 +278,6 @@ 'Zone Thermal Comfort Fanger Model PPD(East Zone PEOPLE)', 'Zone People Occupant Count(East Zone)', 'People Air Temperature(East Zone PEOPLE)', - 'Zone Lights Total Heating Rate(East Zone)', - 'Zone Lights Total Heating Rate(West Zone)', 'Facility Total HVAC Electricity Demand Rate(Whole Building)' ] diff --git a/sinergym/version.txt b/sinergym/version.txt index 3e3c2f1e5e..eca07e4c1a 100644 --- a/sinergym/version.txt +++ b/sinergym/version.txt @@ -1 +1 @@ -2.1.1 +2.1.2 diff --git a/tests/test_constants.py b/tests/test_constants.py new file mode 100644 index 0000000000..ca071c50d4 --- /dev/null +++ b/tests/test_constants.py @@ -0,0 +1,19 @@ +from sinergym.utils.constants import * + + +def test_normalization_dicts(): + # 5ZONE + assert (all(norm_variable in RANGES_5ZONE.keys() + for norm_variable in DEFAULT_5ZONE_OBSERVATION_VARIABLES)) + + # DATACENTER + assert (all(norm_variable in RANGES_DATACENTER.keys() + for norm_variable in DEFAULT_DATACENTER_OBSERVATION_VARIABLES)) + + # OFFICEMEDIUM + assert (all(norm_variable in RANGES_OFFICE.keys() + for norm_variable in DEFAULT_OFFICE_OBSERVATION_VARIABLES)) + + # WAREHOUSE + assert (all(norm_variable in RANGES_WAREHOUSE.keys() + for norm_variable in DEFAULT_WAREHOUSE_OBSERVATION_VARIABLES))