Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

replace EMS with AvailabilityManagerOptimumStart #1631

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 9 additions & 96 deletions lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb
Original file line number Diff line number Diff line change
Expand Up @@ -270,103 +270,16 @@ def air_loop_hvac_optimum_start_required?(air_loop_hvac)
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
# @return [Boolean] returns true if successful, false if not
def air_loop_hvac_enable_optimum_start(air_loop_hvac)
# Get the heating and cooling setpoint schedules
# for all zones on this airloop.
htg_clg_schs = []
air_loop_hvac.thermalZones.each do |zone|
# Skip zones with no thermostat
next if zone.thermostatSetpointDualSetpoint.empty?

# Get the heating and cooling setpoint schedules
tstat = zone.thermostatSetpointDualSetpoint.get
htg_sch = nil
if tstat.heatingSetpointTemperatureSchedule.is_initialized
htg_sch = tstat.heatingSetpointTemperatureSchedule.get
else
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.AirLoopHVAC', "For #{zone.name}: Cannot find a heating setpoint schedule for this zone, cannot apply optimum start control.")
next
end
clg_sch = nil
if tstat.coolingSetpointTemperatureSchedule.is_initialized
clg_sch = tstat.coolingSetpointTemperatureSchedule.get
else
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.standards.AirLoopHVAC', "For #{zone.name}: Cannot find a cooling setpoint schedule for this zone, cannot apply optimum start control.")
next
end
htg_clg_schs << [htg_sch, clg_sch]
end

# Clean name of airloop
loop_name_clean = air_loop_hvac.name.get.to_s.gsub(/\W/, '').delete('_')
# If the name starts with a number, prepend with a letter
if loop_name_clean[0] =~ /[0-9]/
loop_name_clean = "SYS#{loop_name_clean}"
end

# Sensors
oat_db_c_sen = OpenStudio::Model::EnergyManagementSystemSensor.new(air_loop_hvac.model, 'Site Outdoor Air Drybulb Temperature')
oat_db_c_sen.setName('OAT')
oat_db_c_sen.setKeyName('Environment')

# Make a program for each unique set of schedules.
# For most air loops, all zones will have the same
# pair of schedules.
htg_clg_schs.uniq.each_with_index do |htg_clg_sch, i|
htg_sch = htg_clg_sch[0]
clg_sch = htg_clg_sch[1]

if htg_sch.to_ScheduleConstant.is_initialized
htg_sch_type = 'Schedule:Constant'
elsif htg_sch.to_ScheduleCompact.is_initialized
htg_sch_type = 'Schedule:Compact'
else
htg_sch_type = 'Schedule:Year'
end

if clg_sch.to_ScheduleCompact.is_initialized
clg_sch_type = 'Schedule:Constant'
elsif clg_sch.to_ScheduleCompact.is_initialized
clg_sch_type = 'Schedule:Compact'
else
clg_sch_type = 'Schedule:Year'
end

# Actuators
htg_sch_act = OpenStudio::Model::EnergyManagementSystemActuator.new(htg_sch, htg_sch_type, 'Schedule Value')
htg_sch_act.setName("#{loop_name_clean}HtgSch#{i}")

clg_sch_act = OpenStudio::Model::EnergyManagementSystemActuator.new(clg_sch, clg_sch_type, 'Schedule Value')
clg_sch_act.setName("#{loop_name_clean}ClgSch#{i}")

# Programs
optstart_prg = OpenStudio::Model::EnergyManagementSystemProgram.new(air_loop_hvac.model)
optstart_prg.setName("#{loop_name_clean}OptimumStartProg#{i}")
optstart_prg_body = <<-EMS
IF DaylightSavings==0 && DayOfWeek>1 && Hour==5 && #{oat_db_c_sen.handle}<23.9 && #{oat_db_c_sen.handle}>1.7
SET #{clg_sch_act.handle} = 29.4
SET #{htg_sch_act.handle} = 15.6
ELSEIF DaylightSavings==0 && DayOfWeek==1 && Hour==7 && #{oat_db_c_sen.handle}<23.9 && #{oat_db_c_sen.handle}>1.7
SET #{clg_sch_act.handle} = 29.4
SET #{htg_sch_act.handle} = 15.6
ELSEIF DaylightSavings==1 && DayOfWeek>1 && Hour==4 && #{oat_db_c_sen.handle}<23.9 && #{oat_db_c_sen.handle}>1.7
SET #{clg_sch_act.handle} = 29.4
SET #{htg_sch_act.handle} = 15.6
ELSEIF DaylightSavings==1 && DayOfWeek==1 && Hour==6 && #{oat_db_c_sen.handle}<23.9 && #{oat_db_c_sen.handle}>1.7
SET #{clg_sch_act.handle} = 29.4
SET #{htg_sch_act.handle} = 15.6
ELSE
SET #{clg_sch_act.handle} = NULL
SET #{htg_sch_act.handle} = NULL
ENDIF
EMS
optstart_prg.setBody(optstart_prg_body)

# Program Calling Managers
setup_mgr = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(air_loop_hvac.model)
setup_mgr.setName("#{loop_name_clean}OptimumStartCallingManager#{i}")
setup_mgr.setCallingPoint('BeginTimestepBeforePredictor')
setup_mgr.addProgram(optstart_prg)
end
avm_os = OpenStudio::Model::AvailabilityManagerOptimumStart.new(air_loop_hvac.model)
avm_os.setName("#{air_loop_hvac.name.get} Optimum Start Availability Manager")
avm_os.setControlAlgorithm('AdaptiveTemperatureGradient')
# these are defaults, but set here for visibility
avm_os.setInitialTemperatureGradientduringCooling(2)
avm_os.setInitialTemperatureGradientduringHeating(2)
avm_os.setNumberofPreviousDays(3)
# add availability manager
air_loop_hvac.addAvailabilityManager(avm_os)

OpenStudio.logFree(OpenStudio::Info, 'openstudio.standards.AirLoopHVAC', "For #{air_loop_hvac.name}: Optimum start control enabled.")

Expand Down