# accim - Adaptive-Comfort-Control-Implemented Model
# Copyright (C) 2021-2025 Daniel Sánchez-García
# accim is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# any later version.
# accim is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
import besos.IDF_class
# def modify_VSToffset(building, value):
# import accim.sim.accis_single_idf_funcs as accis
# accis.modifyAccis(
# idf=building,
# ComfStand=1,
# CAT=3,
# ComfMod=3,
# # SetpointAcc=1000,
# HVACmode=2,
# VentCtrl=0,
# CoolSeasonStart='01/02',
# CoolSeasonEnd='01/03',
# VSToffset=value,
# # MinOToffset=50,
# # MaxWindSpeed=50
# )
# return
[docs]
def get_valid_param_combinations():
# CS_CA_CM_list_dict = {
# 0:{
# 'name': '0 = ESP CTE',
# 'CAT': ['n/a'],
# 'ComfMod': ['n/a'],
# },
# 0: {
# 'name': ,
# 'CAT': ,
# 'ComfMod': ,
# },
#
# }
# '0 = ESP CTE': [, ],
# '1 = INT EN16798-1': [[1, 2, 3], [0, 1, 2, 3]],
# '2 = INT ASHRAE55': [[80, 90], [0, 1, 2, 3]],
# '3 = JPN Rijal': [[80, 90], [0, 1, 2, 3]],
# '4 = CHN GBT50785 Cold': [[1, 2], [3]],
# '5 = CHN GBT50785 HotMild': [[1, 2], [3]],
# '6 = CHN Yang': [[80, 90], [0, 1, 2, 3]],
# '7 = IND IMAC C NV': [[80, 85, 90], [0, 1, 2, 3]],
# '8 = IND IMAC C MM': [[80, 85, 90], [0, 1, 2, 3]],
# '9 = IND IMAC R 7DRM': [[80, 90], [0, 1, 2, 3]],
# '10 = IND IMAC R 30DRM': [[80, 90], [0, 1, 2, 3]],
# '11 = IND Dhaka': [[80, 90], [0, 1, 2, 3]],
# '12 = ROM Udrea': [[80, 90], [0, 1, 2, 3]],
# '13 = AUS Williamson': [[80, 90], [0.1, 0.2, 0.3, 0.4, 0.5, 1.1, 1.2, 1.3, 1.4, 1.5, 2, 3]],
# '14 = AUS DeDear': [[80, 90], [0.1, 0.2, 0.3, 0.4, 0.5, 1.1, 1.2, 1.3, 1.4, 1.5, 2, 3]],
# '15 = BRA Rupp NV': [[80, 90], [0, 1, 2, 3]],
# '16 = BRA Rupp AC': [[80, 90], [0, 1, 2, 3]],
# '17 = MEX Oropeza Arid': [[80, 90], [0, 1, 2, 3]],
# '18 = MEX Oropeza DryTropic': [[80, 90], [0, 1, 2, 3]],
# '19 = MEX Oropeza Temperate': [[80, 90], [0, 1, 2, 3]],
# '20 = MEX Oropeza HumTropic': [[80, 90], [0, 1, 2, 3]],
# '21 = CHL Perez-Fargallo': [[80, 90], [2, 3]],
# '22 = INT ISO7730': [[1, 2, 3], [0]],
# }
CS_CA_CM_list_dict = {
0: [['n/a'], ['n/a']],
1: [[1, 2, 3], [0, 1, 2, 3]],
2: [[80, 90], [0, 1, 2, 3]],
3: [[80, 90], [0, 1, 2, 3]],
4: [[1, 2], [3]],
5: [[1, 2], [3]],
6: [[80, 90], [0, 1, 2, 3]],
7: [[80, 85, 90], [0, 1, 2, 3]],
8: [[80, 85, 90], [0, 1, 2, 3]],
9: [[80, 90], [0, 1, 2, 3]],
10: [[80, 90], [0, 1, 2, 3]],
11: [[80, 90], [0, 1, 2, 3]],
12: [[80, 90], [0, 1, 2, 3]],
13: [[80, 90], [0.1, 0.2, 0.3, 0.4, 0.5, 1.1, 1.2, 1.3, 1.4, 1.5, 2, 3]],
14: [[80, 90], [0.1, 0.2, 0.3, 0.4, 0.5, 1.1, 1.2, 1.3, 1.4, 1.5, 2, 3]],
15: [[80, 90], [0, 1, 2, 3]],
16: [[80, 90], [0, 1, 2, 3]],
17: [[80, 90], [0, 1, 2, 3]],
18: [[80, 90], [0, 1, 2, 3]],
19: [[80, 90], [0, 1, 2, 3]],
20: [[80, 90], [0, 1, 2, 3]],
21: [[80, 90], [2, 3]],
22: [[1, 2, 3], [0]],
}
return CS_CA_CM_list_dict
[docs]
def drop_invalid_param_combinations(samples_df):
samples_df = samples_df.dropna()
valid_params = {
0: [['n/a'], ['n/a']],
1: [[1, 2, 3], [0, 1, 2, 3]],
2: [[80, 90], [0, 1, 2, 3]],
3: [[80, 90], [0, 1, 2, 3]],
4: [[1, 2], [3]],
5: [[1, 2], [3]],
6: [[80, 90], [0, 1, 2, 3]],
7: [[80, 85, 90], [0, 1, 2, 3]],
8: [[80, 85, 90], [0, 1, 2, 3]],
9: [[80, 90], [0, 1, 2, 3]],
10: [[80, 90], [0, 1, 2, 3]],
11: [[80, 90], [0, 1, 2, 3]],
12: [[80, 90], [0, 1, 2, 3]],
13: [[80, 90], [0.1, 0.2, 0.3, 0.4, 0.5, 1.1, 1.2, 1.3, 1.4, 1.5, 2, 3]],
14: [[80, 90], [0.1, 0.2, 0.3, 0.4, 0.5, 1.1, 1.2, 1.3, 1.4, 1.5, 2, 3]],
15: [[80, 90], [0, 1, 2, 3]],
16: [[80, 90], [0, 1, 2, 3]],
17: [[80, 90], [0, 1, 2, 3]],
18: [[80, 90], [0, 1, 2, 3]],
19: [[80, 90], [0, 1, 2, 3]],
20: [[80, 90], [0, 1, 2, 3]],
21: [[80, 90], [2, 3]],
22: [[1, 2, 3], [0]],
}
samples_df['valid'] = True
for i in samples_df.index:
try:
if samples_df.loc[i, 'CAT'] not in valid_params[samples_df.loc[i, 'ComfStand']][0]:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'ComfMod'] not in valid_params[samples_df.loc[i, 'ComfStand']][1]:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'VentCtrl'] != 0 and samples_df.loc[i, 'HVACmode'] == 0:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'VSToffset'] != 0 and samples_df.loc[i, 'HVACmode'] == 0:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'MinOToffset'] != 0 and samples_df.loc[i, 'HVACmode'] == 0:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'MaxWindSpeed'] != 0 and samples_df.loc[i, 'HVACmode'] == 0:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'SetpointAcc'] < 0:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'MaxTempDiffVOF'] <= 0:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'MinTempDiffVOF'] <= 0:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'MinTempDiffVOF'] >= samples_df.loc[i, 'MaxTempDiffVOF'] <= 0:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
try:
if samples_df.loc[i, 'MultiplierVOF'] < 0 or samples_df.loc[i, 'MultiplierVOF'] > 1:
samples_df.loc[i, 'valid'] = False
except KeyError:
continue
samples_cleaned = samples_df[samples_df['valid'] == True].drop(columns=['valid'])
return samples_cleaned
[docs]
def modify_ComfStand(idf: besos.IDF_class, value: int):
"""
Modifies the ComfStand argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_1 = f'set ComfStand = {value}'
return
[docs]
def modify_CustAST_ACSTaul(idf: besos.IDF_class, value: float):
"""
Modifies the CustAST_ACSTaul argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAppLimits = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAppLimits'][0])
SetAppLimits.Program_Line_2 = f'set ACSTaul = {value}'
return
[docs]
def modify_CustAST_ACSTall(idf: besos.IDF_class, value: float):
"""
Modifies the CustAST_ACSTall argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAppLimits = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAppLimits'][0])
SetAppLimits.Program_Line_3 = f'set ACSTall = {value}'
return
[docs]
def modify_CustAST_AHSTaul(idf: besos.IDF_class, value: float):
"""
Modifies the CustAST_AHSTaul argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAppLimits = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAppLimits'][0])
SetAppLimits.Program_Line_4 = f'set AHSTaul = {value}'
return
[docs]
def modify_CustAST_AHSTall(idf: besos.IDF_class, value: float):
"""
Modifies the CustAST_AHSTall argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAppLimits = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAppLimits'][0])
SetAppLimits.Program_Line_5 = f'set AHSTall = {value}'
return
[docs]
def modify_CustAST_ASTall(idf: besos.IDF_class, value: float):
"""
Modifies the CustAST_ACSTall and CustAST_AHSTall arguments to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAppLimits = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAppLimits'][0])
SetAppLimits.Program_Line_3 = f'set ACSTall = {value}'
SetAppLimits.Program_Line_5 = f'set AHSTall = {value}'
return
[docs]
def modify_CustAST_ASTaul(idf: besos.IDF_class, value: float):
"""
Modifies the CustAST_ACSTaul and CustAST_AHSTaul arguments to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAppLimits = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAppLimits'][0])
SetAppLimits.Program_Line_2 = f'set ACSTaul = {value}'
SetAppLimits.Program_Line_4 = f'set AHSTaul = {value}'
return
[docs]
def modify_CustAST_m(idf: besos.IDF_class, value: float):
"""
Modifies the CustAST_m argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAST = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAST'][0])
SetAST.Program_Line_2 = f'set m = {value}'
return
[docs]
def modify_CustAST_n(idf: besos.IDF_class, value: float):
"""
Modifies the CustAST_n argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAST = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAST'][0])
SetAST.Program_Line_3 = f'set n = {value}'
return
[docs]
def modify_CustAST_ACSToffset(idf: besos.IDF_class, value: float):
"""
Modifies the ACSToffset argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
ApplyCAT = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'ApplyCAT'][0])
ApplyCAT.Program_Line_4 = f'set ACSToffset = {value}'
return
[docs]
def modify_CustAST_AHSToffset(idf: besos.IDF_class, value: float):
"""
Modifies the AHSToffset argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
ApplyCAT = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'ApplyCAT'][0])
ApplyCAT.Program_Line_5 = f'set AHSToffset = {value}'
return
[docs]
def modify_CustAST_ASToffset(idf: besos.IDF_class, value: float):
"""
Modifies the ACSToffset and AHSToffset arguments symmetrically to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
ApplyCAT = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'ApplyCAT'][0])
ApplyCAT.Program_Line_4 = f'set ACSToffset = {value}'
ApplyCAT.Program_Line_5 = f'set AHSToffset = {-value}'
return
[docs]
def modify_CAT(idf: besos.IDF_class, value: int):
"""
Modifies the CAT argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_2 = f'set CAT = {value}'
return
[docs]
def modify_CATcoolOffset(idf: besos.IDF_class, value: float):
"""
Modifies the CATcoolOffset argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
ApplyCAT = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'ApplyCAT'][0])
ApplyCAT.Program_Line_1 = f'set CATcoolOffset = {value}'
return
[docs]
def modify_CATheatOffset(idf: besos.IDF_class, value: float):
"""
Modifies the CATheatOffset argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
ApplyCAT = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'ApplyCAT'][0])
ApplyCAT.Program_Line_2 = f'set CATheatOffset = {value}'
return
[docs]
def modify_ComfMod(idf: besos.IDF_class, value: float):
"""
Modifies the ComfMod argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_3 = f'set ComfMod = {value}'
return
[docs]
def modify_HVACmode(idf: besos.IDF_class, value: int):
"""
Modifies the HVACmode argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_4 = f'set HVACmode = {value}'
return
[docs]
def modify_VentCtrl(idf: besos.IDF_class, value: int):
"""
Modifies the VentCtrl argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_5 = f'set VentCtrl = {value}'
return
[docs]
def modify_VSToffset(idf: besos.IDF_class, value: float):
"""
Modifies the VSToffset argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_6 = f'set VSToffset = {value}'
return
[docs]
def modify_MinOToffset(idf: besos.IDF_class, value: float):
"""
Modifies the MinOToffset argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_7 = f'set MinOToffset = {value}'
return
[docs]
def modify_MaxWindSpeed(idf: besos.IDF_class, value: float):
"""
Modifies the MaxWindSpeed argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_8 = f'set MaxWindSpeed = {value}'
return
[docs]
def modify_ASTtol(idf: besos.IDF_class, value: float):
"""
Modifies the ACSTtol and AHSTtol arguments symmetrically to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
SetInputData.Program_Line_9 = f'set ACSTtol = {-value}'
SetInputData.Program_Line_10 = f'set AHSTtol = {value}'
return
[docs]
def modify_CoolSeasonStart(idf: besos.IDF_class, value: any):
"""
Modifies the CoolSeasonStart argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument. Can be an integer representing the day of the year, or the
date in format dd/mm.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
if type(value) is str:
from accim.utils import transform_ddmm_to_int
value = transform_ddmm_to_int(value)
SetInputData.Program_Line_11 = f'set CoolSeasonStart = {value}'
return
[docs]
def modify_CoolSeasonEnd(idf: besos.IDF_class, value: any):
"""
Modifies the CoolSeasonEnd argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument. Can be an integer representing the day of the year, or the
date in format dd/mm.
:return:
"""
SetInputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetInputData'][0])
if type(value) is str:
from accim.utils import transform_ddmm_to_int
value = transform_ddmm_to_int(value)
SetInputData.Program_Line_12 = f'set CoolSeasonEnd = {value}'
return
[docs]
def modify_SetpointAcc(idf: besos.IDF_class, value: float):
"""
Modifies the SetpointAcc argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetAST = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetAST'][0])
SetAST.Program_Line_1 = f'set SetpointAcc = {value}'
return
[docs]
def modify_MaxTempDiffVOF(idf: besos.IDF_class, value: float):
"""
Modifies the MaxTempDiffVOF argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetVOFinputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetVOFinputData'][0])
SetVOFinputData.Program_Line_1 = f'set MaxTempDiffVOF = {value}'
return
[docs]
def modify_MinTempDiffVOF(idf: besos.IDF_class, value: float):
"""
Modifies the MinTempDiffVOF argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetVOFinputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetVOFinputData'][0])
SetVOFinputData.Program_Line_2 = f'set MinTempDiffVOF = {value}'
return
[docs]
def modify_MultiplierVOF(idf: besos.IDF_class, value: int):
"""
Modifies the MultiplierVOF argument to match the entered value.
:param idf: The eppy or besos IDF class instance.
:param value: The value to be applied in the argument.
:return:
"""
SetVOFinputData = ([program for program in idf.idfobjects['EnergyManagementSystem:Program'] if
program.Name == 'SetVOFinputData'][0])
SetVOFinputData.Program_Line_3 = f'set MultiplierVOF = {value}'
return