<jupyter_start><jupyter_text>Apartments2Thermal Wrapper notebook example In this example,  we demonstrate the use of wrappers around an Energym environment to create new environments that are more suitable for control.<jupyter_code>from energym.examples.Controller import LabController<jupyter_output><empty_output><jupyter_text>Next, we import Energym and create the simulation environment by specifying the model, a weather file and the number of simulation days.<jupyter_code>import energym

weather = "ESP_CT_Barcelona"
env = energym.make("Apartments2Thermal-v0", weather=weather, simulation_days=300)<jupyter_output>C:\Users\PSh\AppData\Local\Continuum\anaconda3\envs\Opti\lib\site-packages\pandas\core\indexing.py:494: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: http://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  self.obj[item] = s<jupyter_text>The control inputs can be inspected using the `get_inputs_names()` method and to construct a controller, we pass the list of inputs and further parameters. This controller determines inputs to get close to the temperature setpoints and uses fixed setpoints during the night.<jupyter_code>inputs = env.get_inputs_names()
print(inputs)
controller = LabController(control_list=inputs, lower_tol=0.3, upper_tol=0.8, nighttime_setback=True, nighttime_start=18, nighttime_end=6, nighttime_temp=18)<jupyter_output>['Bd_Ch_EV1Bat_sp', 'Bd_Ch_EV2Bat_sp', 'Bd_Pw_Bat_sp', 'P1_T_Thermostat_sp', 'P1_onoff_HP_sp', 'P2_T_Thermostat_sp', 'P2_onoff_HP_sp', 'P3_T_Thermostat_sp', 'P3_onoff_HP_sp', 'P4_T_Thermostat_sp', 'P4_onoff_HP_sp']<jupyter_text>The default environment has 480 steps per day, which may be too much for MPC controllers. It is possible to reduce the number of steps per day, adding custom operations (averaging, taking last value) for every variable, as demonstrated below<jupyter_code>#Import the wrappers
from energym.wrappers.downsample_outputs import DownsampleOutputs
from energym.wrappers.rescale_outputs import RescaleOutputs
from energym.wrappers.rescale_inputs import RescaleInputs
from energym.wrappers.rl_wrapper import RLWrapper

#Create an easy downsampling dictionary function
#Here we will always average over the values we got for all variables. Not that this is not necessarily what we want for all variables
# but it is convenient as an example

import numpy as np
steps = 5
downsampling_dic = {}
for key in env.get_outputs_names():
    downsampling_dic[key] = np.mean
    

#We also create an easy reward function, here only lookging at the first room tmp
def reward(outputs:dict):
    value = (outputs['Z01_T'] -0.5)**2
    return value

lower_bound = {'Ext_T':0.0}
upper_bound = {'Ext_T':30.0}
#We create a two layer wrapper. We both downsample and add rewards computation
env_down = DownsampleOutputs(env, steps, downsampling_dic)
env_down_res = RescaleOutputs(env_down,lower_bound, upper_bound) #By default, the variables are rescaled between 0 and 1
env_down_res = RescaleInputs(env_down_res) #By defaults, the variables are rescaled between 0 and 1
#env_down_RL = RLWrapper(env_down_res, reward)  #Always put RLwrapper at the end
outputs = env_down_res.get_output()
outputs
steps = 96*1
out_list = []
rew_list = []
outputs = env_down_res.get_output()
controls = []
hour = 0
for i in range(steps):
    control = controller.get_control(env_down_res.revert_outputs(outputs), 21, hour)
    control['Bd_Ch_EV1Bat_sp'] = [0.0]
    control['Bd_Ch_EV2Bat_sp'] = [0.0]
    controls +=[ {p:control[p][0] for p in control} ]
    outputs = env_down_res.step(env_down_res.revert_inputs(control))
    _,hour,_,_ = env_down_res.get_date()
    out_list.append(outputs)
#Revert values for checks
env_down_res.revert_inputs(control)
env_down_res.revert_outputs(outputs)
env_down_res.get_forecast()<jupyter_output><empty_output><jupyter_text>Since the inputs and outputs are given as dictionaries and are collected in lists, we can simply load them as a pandas.DataFrame.<jupyter_code>import pandas as pd
out_df = pd.DataFrame(out_list)<jupyter_output><empty_output><jupyter_text>To generate plots, we can directly get the data from the DataFrames, by using the key names. Displayed are the zone temperatures and the setpoints determined by the controller for zone 1 as well as the corresponding heat pump on/off switching, the external temperature, and the total power demand.<jupyter_code>import matplotlib.pyplot as plt
%matplotlib notebook

f, (ax1,ax2,ax3) = plt.subplots(3,figsize=(10,15))#


ax1.plot(out_df['Z01_T'], 'r')
ax1.plot(out_df['P1_T_Thermostat_sp_out'], 'b--')
ax1.plot(out_df['P1_onoff_HP_sp_out'], 'g+' )
ax1.set_ylabel('Temp')
ax1.set_xlabel('Steps')

ax2.plot(out_df['Ext_T'], 'r')
ax2.set_ylabel('Temp')
ax2.set_xlabel('Steps')

ax3.plot(out_df['Fa_Pw_All'], 'g')
ax3.set_ylabel('Power')
ax3.set_xlabel('Steps')

plt.subplots_adjust(hspace=0.4)

plt.show()<jupyter_output><empty_output><jupyter_text>To end the simulation, the `close()` method is called. It deletes files that were produced during the simulation and stores some information about the simulation in the *runs* folder.<jupyter_code>env.close()<jupyter_output>[OK] fmi2Terminate: fmiFreeInstanceSlave must be called to free the FMU instance.

[OK] fmi2FreeInstance: The function fmi2FreeInstance of instance %s is executed.

[OK] freeInstanceResources: %s will be freed.
{'fraction_non_alphanumeric': 0.09194776931447225, 'fraction_numerical': 0.016140732680449764, 'mean_word_length': 6.47289972899729, 'pattern_counts': {'":': 0, '<': 26, '<?xml version=': 0, '>': 26, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '337011', 'license': 'CC-BY-4.0', 'n_tokens_mistral': 1910, 'n_tokens_neox': 1837, 'n_words': 531, 'path': 'notebooks/Apartments2Thermal_wrapper.ipynb', 'repo_name': 'bsl546/energym', 'size': '5514'}