Source code for accim.sim.accim_ExistingHVAC_EMS

# 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/>.

"""Module for EMS functions and models with existing HVAC systems"""


[docs] def addEMSSensorsExisHVAC(self, verboseMode : bool = True): """ Adds the EMS sensors for models with existing HVAC system. :param self: Used as a method for class ``accim.sim.accim_Main.accimJob`` :param verboseMode: Inherited from class ``accim.sim.accis.addAccis`` """ sensorlist = ([sensor.Name for sensor in self.idf1.idfobjects['EnergyManagementSystem:Sensor']]) for i in range(len(self.ExisHVAC)): for j in range(len(self.ExisHVAC[i][1])): if 'Cool' in self.ExisHVAC[i][1][j] or 'Cool' in self.HVACdict[self.ExisHVAC[i][0]]: zone_for_coil = self.ExisHVAC[i][3][j] matching_ems_names = [] if hasattr(self, 'ems_zonenames') and hasattr(self, 'ems_objs_name'): for z_idx, z_name in enumerate(self.ems_zonenames): if z_name.upper() == zone_for_coil.upper(): matching_ems_names.append(self.ems_objs_name[z_idx]) if not matching_ems_names: matching_ems_names.append(zone_for_coil) for ems_name in matching_ems_names: if ems_name + '_CoolCoil' in sensorlist: if verboseMode: print('Not added - ' + ems_name + '_CoolCoil Sensor') else: self.idf1.newidfobject( 'EnergyManagementSystem:Sensor', Name=ems_name + '_CoolCoil', OutputVariable_or_OutputMeter_Index_Key_Name=self.ExisHVAC[i][1][j], OutputVariable_or_OutputMeter_Name=self.HVACdict[self.ExisHVAC[i][0]] ) sensorlist.append(ems_name + '_CoolCoil') if verboseMode: print('Added - ' + ems_name + '_CoolCoil Sensor') for k in range(len(self.ExisHVAC[i][4])): if self.ExisHVAC[i][3][j].lower() in self.ExisHVAC[i][4][k].lower(): if self.ExisHVAC[i][4][k] + '_CoolCoil' in sensorlist: if verboseMode: print('Not added - ' + self.ExisHVAC[i][4][k] + '_CoolCoil Sensor') else: self.idf1.newidfobject( 'EnergyManagementSystem:Sensor', Name=self.ExisHVAC[i][4][k] + '_CoolCoil', OutputVariable_or_OutputMeter_Index_Key_Name=self.ExisHVAC[i][1][j], OutputVariable_or_OutputMeter_Name=self.HVACdict[self.ExisHVAC[i][0]] ) sensorlist.append(self.ExisHVAC[i][4][k] + '_CoolCoil') if verboseMode: print('Added - ' + self.ExisHVAC[i][4][k] + '_CoolCoil Sensor') # print([sensor for sensor in self.idf1.idfobjects['EnergyManagementSystem:Sensor'] if sensor.Name==self.ExisHVAC[i][3][j]+'_CoolCoil']) if 'Heating' in self.ExisHVAC[i][1][j] or 'Heating' in self.HVACdict[self.ExisHVAC[i][0]]: zone_for_coil = self.ExisHVAC[i][3][j] matching_ems_names = [] if hasattr(self, 'ems_zonenames') and hasattr(self, 'ems_objs_name'): for z_idx, z_name in enumerate(self.ems_zonenames): if z_name.upper() == zone_for_coil.upper(): matching_ems_names.append(self.ems_objs_name[z_idx]) if not matching_ems_names: matching_ems_names.append(zone_for_coil) for ems_name in matching_ems_names: if ems_name + '_HeatCoil' in sensorlist: if verboseMode: print('Not added - ' + ems_name + '_HeatCoil Sensor') else: self.idf1.newidfobject( 'EnergyManagementSystem:Sensor', Name=ems_name + '_HeatCoil', OutputVariable_or_OutputMeter_Index_Key_Name=self.ExisHVAC[i][1][j], OutputVariable_or_OutputMeter_Name=self.HVACdict[self.ExisHVAC[i][0]] ) sensorlist.append(ems_name + '_HeatCoil') if verboseMode: print('Added - ' + ems_name + '_HeatCoil Sensor') # probando for k in range(len(self.ExisHVAC[i][4])): if self.ExisHVAC[i][3][j].lower() in self.ExisHVAC[i][4][k].lower(): if self.ExisHVAC[i][4][k] + '_HeatCoil' in sensorlist: if verboseMode: print('Not added - ' + self.ExisHVAC[i][4][k] + '_HeatCoil Sensor') else: self.idf1.newidfobject( 'EnergyManagementSystem:Sensor', Name=self.ExisHVAC[i][4][k] + '_HeatCoil', OutputVariable_or_OutputMeter_Index_Key_Name=self.ExisHVAC[i][1][j], OutputVariable_or_OutputMeter_Name=self.HVACdict[self.ExisHVAC[i][0]] ) sensorlist.append(self.ExisHVAC[i][4][k] + '_HeatCoil') if verboseMode: print('Added - ' + self.ExisHVAC[i][4][k] + '_HeatCoil Sensor') # Keep the list of coil sensors for the init program self._exis_hvac_coil_sensors = [s for s in sensorlist if s.endswith('_CoolCoil') or s.endswith('_HeatCoil')] del sensorlist
[docs] def addEMSInitExisHVAC(self, verboseMode: bool = True): """ Adds an EMS Program and ProgramCallingManager with BeginNewEnvironment calling point to initialize all coil sensor variables to 0. This prevents EnergyPlus from raising a fatal "variable not initialized" error at the very first timestep, before the HVAC system has produced any output values. :param self: Used as a method for class ``accim.sim.accim_Main.accimJob`` :param verboseMode: Inherited from class ``accim.sim.accis.addAccis`` """ programlist = [p.Name for p in self.idf1.idfobjects['EnergyManagementSystem:Program']] pcmlist = [p.Name for p in self.idf1.idfobjects['EnergyManagementSystem:ProgramCallingManager']] init_prog_name = 'InitExisHVACCoils' if init_prog_name in programlist: if verboseMode: print(f'Not added - {init_prog_name} Program (already exists)') return coil_sensors = getattr(self, '_exis_hvac_coil_sensors', []) if not coil_sensors: # Fall back: derive from ems_objs_name coil_sensors = [] for name in getattr(self, 'ems_objs_name', []): coil_sensors.append(name + '_CoolCoil') coil_sensors.append(name + '_HeatCoil') if not coil_sensors: if verboseMode: print(f'No coil sensors found, skipping {init_prog_name}') return # Build kwargs for newidfobject: each SET line initialises one sensor variable prog_kwargs = {'Name': init_prog_name} for idx, sensor_name in enumerate(coil_sensors, start=1): prog_kwargs[f'Program_Line_{idx}'] = f'SET {sensor_name} = 0' self.idf1.newidfobject('EnergyManagementSystem:Program', **prog_kwargs) if verboseMode: print(f'Added - {init_prog_name} Program ({len(coil_sensors)} coil variables initialised)') # Register the init program under BeginNewEnvironment so it runs before any ApplyAST if init_prog_name not in pcmlist: self.idf1.newidfobject( 'EnergyManagementSystem:ProgramCallingManager', Name=init_prog_name, EnergyPlus_Model_Calling_Point='BeginNewEnvironment', Program_Name_1=init_prog_name ) if verboseMode: print(f'Added - {init_prog_name} ProgramCallingManager (BeginNewEnvironment)')