openstudio-standards 0.2.17.rc1 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/data/standards/OpenStudio_Standards-ashrae_90_1.xlsx +0 -0
- data/data/standards/openstudio_standards_duplicates_log.csv +5 -0
- data/lib/openstudio-standards/btap/btap_result.rb +138 -138
- data/lib/openstudio-standards/btap/economics.rb +58 -53
- data/lib/openstudio-standards/btap/envelope.rb +1 -1
- data/lib/openstudio-standards/btap/fileio.rb +12 -12
- data/lib/openstudio-standards/btap/measures.rb +63 -59
- data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.exterior_lights.rb +7 -7
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.Model.rb +5 -1
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.ServiceWaterHeating.rb +8 -0
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.SizingSystem.rb +9 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +53 -23
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +15 -1
- data/lib/openstudio-standards/standards/Standards.Construction.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.Model.rb +18 -18
- data/lib/openstudio-standards/standards/Standards.PlanarSurface.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +1 -1
- data/lib/openstudio-standards/standards/Standards.WaterHeaterMixed.rb +5 -5
- data/lib/openstudio-standards/standards/Standards.ZoneHVACComponent.rb +3 -2
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.AirLoopHVAC.rb +43 -40
- data/lib/openstudio-standards/standards/ashrae_90_1/ashrae_90_1_2019/ashrae_90_1_2019.ZoneHVACComponent.rb +2 -1
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.entryways.json +19 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.parking.json +13 -4
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_1980_2004/doe_ref_1980_2004.AirLoopHVAC.rb +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1/doe_ref_pre_1980/doe_ref_pre_1980.AirLoopHVAC.rb +11 -0
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.AirLoopHVAC.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +9 -9
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlanarSurface.rb +1 -1
- data/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.PlantLoop.rb +5 -1
- data/lib/openstudio-standards/standards/necb/BTAPPRE1980/hvac_system_6.rb +5 -1
- data/lib/openstudio-standards/standards/necb/ECMS/hvac_systems.rb +8 -4
- data/lib/openstudio-standards/standards/necb/ECMS/nv.rb +8 -2
- data/lib/openstudio-standards/standards/necb/NECB2011/hvac_systems.rb +7 -3
- data/lib/openstudio-standards/standards/necb/NECB2011/qaqc/necb_qaqc.rb +4 -4
- data/lib/openstudio-standards/standards/necb/NECB2011/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/standards/necb/NECB2020/service_water_heating.rb +1 -1
- data/lib/openstudio-standards/version.rb +1 -1
- data/lib/openstudio-standards/weather/Weather.Model.rb +5 -0
- metadata +4 -2
@@ -24,28 +24,28 @@ require "#{File.dirname(__FILE__)}/btap"
|
|
24
24
|
|
25
25
|
class OSMArg
|
26
26
|
ARGUMENT_TYPES = [
|
27
|
-
"BOOL",
|
28
|
-
"STRING",
|
29
|
-
"INTEGER",
|
30
|
-
"FLOAT",
|
27
|
+
"BOOL",
|
28
|
+
"STRING",
|
29
|
+
"INTEGER",
|
30
|
+
"FLOAT",
|
31
31
|
"STRINGCHOICE",
|
32
|
-
"WSCHOICE"
|
32
|
+
"WSCHOICE"
|
33
33
|
]
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
attr_accessor :runner,
|
38
|
-
:variable_name,
|
34
|
+
|
35
|
+
|
36
|
+
|
37
|
+
attr_accessor :runner,
|
38
|
+
:variable_name,
|
39
39
|
:type,
|
40
|
-
:required,
|
40
|
+
:required,
|
41
41
|
:model_dependant,
|
42
|
-
:display_name,
|
43
|
-
:default_value,
|
44
|
-
:min_value,
|
45
|
-
:max_value,
|
46
|
-
:string_choice_array,
|
42
|
+
:display_name,
|
43
|
+
:default_value,
|
44
|
+
:min_value,
|
45
|
+
:max_value,
|
46
|
+
:string_choice_array,
|
47
47
|
:os_object_type
|
48
|
-
|
48
|
+
|
49
49
|
def self.bool( variable_name,display_name,required,default_value )
|
50
50
|
raise "#{default_value} defaut value is not a bool." unless default_value.is_a?(Bool)
|
51
51
|
default_value.respond_to?(:to_s)
|
@@ -53,47 +53,47 @@ class OSMArg
|
|
53
53
|
arg.default_value = default_value
|
54
54
|
return arg
|
55
55
|
end
|
56
|
-
|
56
|
+
|
57
57
|
def self.string( variable_name,display_name,required,default_value )
|
58
58
|
raise "#{default_value} defaut value is not a string." unless default_value.respond_to?(:to_s)
|
59
59
|
arg = OSMArg.new( "STRING", variable_name, display_name, required)
|
60
60
|
arg.default_value = default_value
|
61
61
|
return arg
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def self.integer( variable_name,display_name,required,default_value,min_value,max_value )
|
65
65
|
raise "#{default_value} defaut value is not a integer." unless default_value.respond_to?(:to_i)
|
66
66
|
arg = OSMArg.new( "INTEGER", variable_name, display_name, required)
|
67
67
|
arg.default_value = default_value
|
68
68
|
arg.min_value = min_value
|
69
69
|
arg.max_value = max_value
|
70
|
-
return arg
|
70
|
+
return arg
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
def self.float( variable_name, display_name, required,default_value,min_value, max_value )
|
74
74
|
raise "#{default_value} defaut value is not a float." unless default_value.respond_to?(:to_f)
|
75
75
|
arg = OSMArg.new( "INTEGER", variable_name, display_name, required)
|
76
76
|
arg.default_value = default_value
|
77
77
|
arg.min_value = min_value
|
78
78
|
arg.max_value = max_value
|
79
|
-
return arg
|
79
|
+
return arg
|
80
80
|
end
|
81
|
-
|
81
|
+
|
82
82
|
def self.choice(variable_name,display_name,required,default_value,string_choice_array)
|
83
|
-
raise "#{default_value} defaut value is not an array." unless default_value.is_a?(Array)
|
83
|
+
raise "#{default_value} defaut value is not an array." unless default_value.is_a?(Array)
|
84
84
|
arg = OSMArg.new( "STRINGCHOICE", variable_name, display_name, required)
|
85
85
|
arg.default_value = default_value
|
86
86
|
arg.string_choice_array = string_choice_array
|
87
87
|
return arg
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
def self.wschoice( variable_name, display_name, required, default_value, os_object_type)
|
91
91
|
arg = OSMArg.new( "WSCHOICE", variable_name, display_name, required )
|
92
92
|
arg.default_value = default_value
|
93
93
|
arg.os_object_type = os_object_type
|
94
|
-
return arg
|
94
|
+
return arg
|
95
95
|
end
|
96
|
-
|
96
|
+
|
97
97
|
def initialize( type, variable_name, display_name, required )
|
98
98
|
self.type = type
|
99
99
|
self.variable_name = variable_name
|
@@ -106,9 +106,9 @@ class OSMArg
|
|
106
106
|
self.model_dependant = false
|
107
107
|
end
|
108
108
|
return self
|
109
|
-
end
|
109
|
+
end
|
110
110
|
end
|
111
|
-
|
111
|
+
|
112
112
|
|
113
113
|
|
114
114
|
|
@@ -116,10 +116,10 @@ end
|
|
116
116
|
module BTAP
|
117
117
|
module Measures
|
118
118
|
module OSMeasures
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
119
|
+
|
120
|
+
|
121
|
+
|
122
|
+
|
123
123
|
class BTAPModelUserScript < OpenStudio::Ruleset::ModelUserScript
|
124
124
|
#if and E+ measure replace OpenStudio::Ruleset::ModelUserScript with OpenStudio::Ruleset::WorkspaceUserScript
|
125
125
|
#Array containing information of all inputs required by measure.
|
@@ -134,8 +134,8 @@ module BTAP
|
|
134
134
|
"BTAPModelUserScript"
|
135
135
|
OSMArgument.new
|
136
136
|
end
|
137
|
-
|
138
|
-
#this method will output the ruby macro to perform the change.
|
137
|
+
|
138
|
+
#this method will output the ruby macro to perform the change.
|
139
139
|
def generate_ruby_macro(model,runner)
|
140
140
|
if @file == nil or @file == ""
|
141
141
|
@file = "Enter_Path_To_#{self.class.name}_measure.rb_File!"
|
@@ -190,8 +190,8 @@ module BTAP
|
|
190
190
|
if not runner.validateUserArguments(self.arguments(model),user_arguments)
|
191
191
|
return false
|
192
192
|
end
|
193
|
-
|
194
|
-
#Set argument to instance variables.
|
193
|
+
|
194
|
+
#Set argument to instance variables.
|
195
195
|
self.argument_getter(model, runner,user_arguments)
|
196
196
|
#will run the childs method measure_code
|
197
197
|
result = self.measure_code(model,runner)
|
@@ -201,7 +201,7 @@ module BTAP
|
|
201
201
|
|
202
202
|
def argument_setter(model,args)
|
203
203
|
#***boilerplate code starts. Do not edit...
|
204
|
-
|
204
|
+
|
205
205
|
|
206
206
|
#iterate through array of hashes and make arguments based on type and set
|
207
207
|
# max and min values where applicable.
|
@@ -247,7 +247,7 @@ module BTAP
|
|
247
247
|
unless @argument_array == nil
|
248
248
|
@argument_array.each do |row|
|
249
249
|
name = row.variable_name
|
250
|
-
|
250
|
+
|
251
251
|
case row.type
|
252
252
|
when "BOOL"
|
253
253
|
value = runner.getBoolArgumentValue(name, user_arguments)
|
@@ -269,7 +269,7 @@ module BTAP
|
|
269
269
|
value = runner.getDoubleArgumentValue(name, user_arguments)
|
270
270
|
instance_variable_set("@#{name}",value)
|
271
271
|
@arg_table << [name,value]
|
272
|
-
|
272
|
+
|
273
273
|
if ( not row.min_value.nil? and instance_variable_get("@#{name}") < row.min_value ) or ( not row.max_value.nil? and instance_variable_get("@#{name}") > row.max_value )
|
274
274
|
runner.registerError("#{row.display_name} must be greater than or equal to #{row.min_value} and less than or equal to #{row.max_value}. You entered #{instance_variable_get("@#{name}")}.")
|
275
275
|
return false
|
@@ -288,10 +288,10 @@ module BTAP
|
|
288
288
|
end #end do
|
289
289
|
end
|
290
290
|
return @arg_table
|
291
|
-
end
|
292
|
-
|
291
|
+
end
|
292
|
+
|
293
293
|
end
|
294
|
-
#Measure Template simplified.
|
294
|
+
#Measure Template simplified.
|
295
295
|
class TemplateModelMeasure < BTAPModelUserScript
|
296
296
|
|
297
297
|
def name
|
@@ -391,14 +391,14 @@ module BTAP
|
|
391
391
|
def run(model, runner, user_arguments)
|
392
392
|
#run the super
|
393
393
|
parent_method_is_true = super(model, runner, user_arguments)
|
394
|
-
|
395
|
-
|
394
|
+
|
395
|
+
|
396
396
|
###############
|
397
|
-
|
398
|
-
#Set Archetype name in runner.
|
397
|
+
|
398
|
+
#Set Archetype name in runner.
|
399
399
|
runner.registerValue('archetype_name',@archetype_name)
|
400
|
-
|
401
|
-
#Set path to OSM files.
|
400
|
+
|
401
|
+
#Set path to OSM files.
|
402
402
|
alternative_model_path = OpenStudio::Path.new("#{File.dirname(__FILE__)}/#{@archetype_name}.osm")
|
403
403
|
#load model and test.
|
404
404
|
translator = OpenStudio::OSVersion::VersionTranslator.new
|
@@ -561,7 +561,7 @@ module BTAP
|
|
561
561
|
model = self.load_base_model_building()
|
562
562
|
self.set_weather_file(model)
|
563
563
|
self.set_hourly_output(model)
|
564
|
-
|
564
|
+
|
565
565
|
model,log = self.apply_ecms(model,@csv_data)
|
566
566
|
BTAP::FileIO::save_osm( model, "#{output_folder}/#{BTAP::FileIO::get_name(model)}.osm") unless output_folder.nil?
|
567
567
|
File.open("#{output_folder}/#{BTAP::FileIO::get_name(model)}.log", 'w') { |file| file.write(log) } unless output_folder.nil?
|
@@ -621,7 +621,7 @@ module BTAP
|
|
621
621
|
"cost_per_building"
|
622
622
|
]
|
623
623
|
self.set_instance_variables( measure_values )
|
624
|
-
|
624
|
+
|
625
625
|
#cost per building and building area
|
626
626
|
building = model.building.get
|
627
627
|
raise ("you did not enter a cost for measure #{@measure_id}. All measures must have a cost of at least 0.0 . Please add a cost_per_building field.") if @cost_per_building.nil?
|
@@ -753,7 +753,7 @@ module BTAP
|
|
753
753
|
@total_building_construction_set_cost
|
754
754
|
)
|
755
755
|
|
756
|
-
#Give adiabatic surfaces a construction. Does not matter what. This is a bug in
|
756
|
+
#Give adiabatic surfaces a construction. Does not matter what. This is a bug in OpenStudio that leave these surfaces unassigned by the default construction set.
|
757
757
|
all_adiabatic_surfaces = BTAP::Geometry::Surfaces::filter_by_boundary_condition(model.getSurfaces, "Adiabatic")
|
758
758
|
unless all_adiabatic_surfaces.empty?
|
759
759
|
BTAP::Geometry::Surfaces::set_surfaces_construction( all_adiabatic_surfaces, model.building.get.defaultConstructionSet.get.defaultInteriorSurfaceConstructions.get.wallConstruction.get)
|
@@ -772,7 +772,7 @@ module BTAP
|
|
772
772
|
"infiltration_flow_per_exterior_area",
|
773
773
|
"infiltration_air_changes_per_hour"
|
774
774
|
]
|
775
|
-
|
775
|
+
|
776
776
|
#Set all the above instance variables to the @csv_data values or, if not set or == 'na', to nil.
|
777
777
|
self.set_instance_variables(measure_values)
|
778
778
|
|
@@ -811,7 +811,7 @@ module BTAP
|
|
811
811
|
fan.setMotorEfficiency( @fan_motor_eff ) unless @fan_motor_eff.nil?
|
812
812
|
log << fan.name.get.to_s << ",#{fan.fanEfficiency},#{fan.motorEfficiency}\n"
|
813
813
|
end
|
814
|
-
|
814
|
+
|
815
815
|
end
|
816
816
|
|
817
817
|
case @fan_volume_type
|
@@ -975,7 +975,9 @@ module BTAP
|
|
975
975
|
model.getCoilCoolingDXSingleSpeeds.sort.each do |cooling_coil|
|
976
976
|
cooling_coil.setRatedCOP( OpenStudio::OptionalDouble.new( @cop ) ) unless @cop.nil?
|
977
977
|
cop = "NA"
|
978
|
-
|
978
|
+
# Prior to 3.5.0, it was an optional double, now it's a double
|
979
|
+
cop_ = OpenStudio::OptionalDouble.new(cooling_coil.ratedCOP)
|
980
|
+
cop = cop_.get unless cop_.empty?
|
979
981
|
log << cooling_coil.name.get.to_s << ",#{cop}\n"
|
980
982
|
|
981
983
|
end
|
@@ -987,9 +989,11 @@ module BTAP
|
|
987
989
|
cooling_coil.setRatedHighSpeedCOP( @cop ) unless @cop.nil?
|
988
990
|
cooling_coil.setRatedLowSpeedCOP( @cop ) unless @cop.nil?
|
989
991
|
cop_high = "NA"
|
990
|
-
|
992
|
+
cop_ = OpenStudio::OptionalDouble.new(cooling_coil.ratedHighSpeedCOP)
|
993
|
+
cop_high = cop_.get unless cop_.empty?
|
991
994
|
cop_low = "NA"
|
992
|
-
|
995
|
+
cop_ = OpenStudio::OptionalDouble.new(cooling_coil.ratedLowSpeedCOP)
|
996
|
+
cop_low = cop_.get unless cop_.empty?
|
993
997
|
log << cooling_coil.name.get.to_s << ",#{cop_high},#{cop_low}\n"
|
994
998
|
end
|
995
999
|
end
|
@@ -1296,8 +1300,8 @@ module BTAP
|
|
1296
1300
|
@erv_nominal_electric_power,
|
1297
1301
|
@erv_economizer_lockout.to_bool
|
1298
1302
|
).each { |erv| log << erv.to_s }
|
1299
|
-
|
1300
|
-
|
1303
|
+
|
1304
|
+
|
1301
1305
|
#Add setpoint manager to all OA object in airloops.
|
1302
1306
|
model.getHeatExchangerAirToAirSensibleAndLatents.sort.each do |erv|
|
1303
1307
|
|
@@ -99,7 +99,7 @@ class Vintagizer
|
|
99
99
|
new_construction_set.setName(construction_id)
|
100
100
|
constructions_model.building.get.setDefaultConstructionSet( new_construction_set.clone( constructions_model ).to_DefaultConstructionSet.get )
|
101
101
|
|
102
|
-
#Give adiabatic surfaces a construction. Does not matter what. This is a bug in
|
102
|
+
#Give adiabatic surfaces a construction. Does not matter what. This is a bug in OpenStudio that leave these surfaces unassigned by the default construction set.
|
103
103
|
all_adiabatic_surfaces = BTAP::Geometry::Surfaces::filter_by_boundary_condition(constructions_model.getSurfaces, "Adiabatic")
|
104
104
|
BTAP::Geometry::Surfaces::set_surfaces_construction( all_adiabatic_surfaces, constructions_model.building.get.defaultConstructionSet.get.defaultInteriorSurfaceConstructions.get.wallConstruction.get)
|
105
105
|
|
@@ -59,7 +59,7 @@ class Standard
|
|
59
59
|
end
|
60
60
|
|
61
61
|
# add exterior lights for parking area
|
62
|
-
if area_length_count_hash[:parking_area_and_drives_area] > 0
|
62
|
+
if !area_length_count_hash[:parking_area_and_drives_area].nil? && area_length_count_hash[:parking_area_and_drives_area] > 0
|
63
63
|
|
64
64
|
# lighting values
|
65
65
|
multiplier = area_length_count_hash[:parking_area_and_drives_area] * onsite_parking_fraction
|
@@ -86,7 +86,7 @@ class Standard
|
|
86
86
|
end
|
87
87
|
|
88
88
|
# add exterior lights for facades
|
89
|
-
if area_length_count_hash[:building_facades] > 0
|
89
|
+
if !area_length_count_hash[:building_facades].nil? && area_length_count_hash[:building_facades] > 0
|
90
90
|
|
91
91
|
# lighting values
|
92
92
|
multiplier = area_length_count_hash[:building_facades]
|
@@ -113,7 +113,7 @@ class Standard
|
|
113
113
|
end
|
114
114
|
|
115
115
|
# add exterior lights for main entries
|
116
|
-
if area_length_count_hash[:main_entries] > 0
|
116
|
+
if !area_length_count_hash[:main_entries].nil? && area_length_count_hash[:main_entries] > 0
|
117
117
|
|
118
118
|
# lighting values
|
119
119
|
multiplier = area_length_count_hash[:main_entries]
|
@@ -140,7 +140,7 @@ class Standard
|
|
140
140
|
end
|
141
141
|
|
142
142
|
# add exterior lights for other doors
|
143
|
-
if area_length_count_hash[:other_doors] > 0
|
143
|
+
if !area_length_count_hash[:other_doors].nil? && area_length_count_hash[:other_doors] > 0
|
144
144
|
|
145
145
|
# lighting values
|
146
146
|
multiplier = area_length_count_hash[:other_doors]
|
@@ -167,7 +167,7 @@ class Standard
|
|
167
167
|
end
|
168
168
|
|
169
169
|
# add exterior lights for entry canopies
|
170
|
-
if area_length_count_hash[:canopy_entry_area] > 0
|
170
|
+
if !area_length_count_hash[:canopy_entry_area].nil? && area_length_count_hash[:canopy_entry_area] > 0
|
171
171
|
|
172
172
|
# lighting values
|
173
173
|
multiplier = area_length_count_hash[:canopy_entry_area]
|
@@ -194,7 +194,7 @@ class Standard
|
|
194
194
|
end
|
195
195
|
|
196
196
|
# add exterior lights for emergency canopies
|
197
|
-
if area_length_count_hash[:canopy_emergency_area] > 0
|
197
|
+
if !area_length_count_hash[:canopy_emergency_area].nil? && area_length_count_hash[:canopy_emergency_area] > 0
|
198
198
|
|
199
199
|
# lighting values
|
200
200
|
multiplier = area_length_count_hash[:canopy_emergency_area]
|
@@ -221,7 +221,7 @@ class Standard
|
|
221
221
|
end
|
222
222
|
|
223
223
|
# add exterior lights for drive through windows
|
224
|
-
if area_length_count_hash[:drive_through_windows] > 0
|
224
|
+
if !area_length_count_hash[:drive_through_windows].nil? && area_length_count_hash[:drive_through_windows] > 0
|
225
225
|
|
226
226
|
# lighting values
|
227
227
|
multiplier = area_length_count_hash[:drive_through_windows]
|
@@ -2721,7 +2721,11 @@ Standard.class_eval do
|
|
2721
2721
|
end
|
2722
2722
|
end
|
2723
2723
|
end
|
2724
|
-
|
2724
|
+
|
2725
|
+
# check wall area is non-zero
|
2726
|
+
if wwr && wall_area > 0
|
2727
|
+
return window_area / wall_area * 100
|
2728
|
+
end
|
2725
2729
|
|
2726
2730
|
# else
|
2727
2731
|
return window_area
|
@@ -546,6 +546,14 @@ class Standard
|
|
546
546
|
default_water_heater_ambient_temp_sch = model_add_constant_schedule_ruleset(model,
|
547
547
|
OpenStudio.convert(70.0, 'F', 'C').get,
|
548
548
|
name = 'Water Heater Ambient Temp Schedule - 70F')
|
549
|
+
if temp_sch_type_limits.nil?
|
550
|
+
temp_sch_type_limits = model_add_schedule_type_limits(model,
|
551
|
+
name: 'Temperature Schedule Type Limits',
|
552
|
+
lower_limit_value: 0.0,
|
553
|
+
upper_limit_value: 100.0,
|
554
|
+
numeric_type: 'Continuous',
|
555
|
+
unit_type: 'Temperature')
|
556
|
+
end
|
549
557
|
default_water_heater_ambient_temp_sch.setScheduleTypeLimits(temp_sch_type_limits)
|
550
558
|
tank.setAmbientTemperatureIndicator('Schedule')
|
551
559
|
tank.setAmbientTemperatureSchedule(default_water_heater_ambient_temp_sch)
|
@@ -57,14 +57,20 @@ class Standard
|
|
57
57
|
end
|
58
58
|
|
59
59
|
sizing_system = air_loop_hvac.sizingSystem
|
60
|
-
|
61
|
-
|
60
|
+
if air_loop_hvac.model.version < OpenStudio::VersionString.new('3.3.0')
|
61
|
+
sizing_system.setSystemOutdoorAirMethod('VentilationRateProcedure')
|
62
|
+
else
|
63
|
+
sizing_system.setSystemOutdoorAirMethod('Standard62.1VentilationRateProcedure')
|
64
|
+
end
|
65
|
+
|
66
|
+
# Set the minimum zone ventilation efficiency
|
67
|
+
min_ventilation_efficiency = air_loop_hvac_minimum_zone_ventilation_efficiency(air_loop_hvac)
|
62
68
|
air_loop_hvac.thermalZones.sort.each do |zone|
|
63
69
|
sizing_zone = zone.sizingZone
|
64
70
|
if air_loop_hvac.model.version < OpenStudio::VersionString.new('3.0.0')
|
65
71
|
OpenStudio.logFree(OpenStudio::Warn, 'openstudio.prototype.SizingSystem', "The design minimum zone ventilation efficiency cannot be set for #{sizing_system.name}. It can only be set OpenStudio 3.0.0 and later.")
|
66
72
|
else
|
67
|
-
sizing_zone.setDesignMinimumZoneVentilationEfficiency(
|
73
|
+
sizing_zone.setDesignMinimumZoneVentilationEfficiency(min_ventilation_efficiency)
|
68
74
|
end
|
69
75
|
end
|
70
76
|
|
@@ -1757,13 +1757,21 @@ class Standard
|
|
1757
1757
|
# set air loop availability controls and night cycle manager, after oa system added
|
1758
1758
|
air_loop.setAvailabilitySchedule(hvac_op_sch)
|
1759
1759
|
air_loop.setNightCycleControlType('CycleOnAny')
|
1760
|
-
|
1761
|
-
if
|
1762
|
-
avail_mgr =
|
1763
|
-
if avail_mgr.
|
1764
|
-
avail_mgr = avail_mgr.
|
1765
|
-
|
1766
|
-
|
1760
|
+
|
1761
|
+
if model.version < OpenStudio::VersionString.new('3.5.0')
|
1762
|
+
avail_mgr = air_loop.availabilityManager
|
1763
|
+
if avail_mgr.is_initialized
|
1764
|
+
avail_mgr = avail_mgr.get
|
1765
|
+
else
|
1766
|
+
avail_mgr = nil
|
1767
|
+
end
|
1768
|
+
else
|
1769
|
+
avail_mgr = air_loop.availabilityManagers[0]
|
1770
|
+
end
|
1771
|
+
|
1772
|
+
if !avail_mgr.nil? && avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
|
1773
|
+
avail_mgr = avail_mgr.to_AvailabilityManagerNightCycle.get
|
1774
|
+
avail_mgr.setCyclingRunTime(1800)
|
1767
1775
|
end
|
1768
1776
|
|
1769
1777
|
# hook the VAV system to each zone
|
@@ -2113,13 +2121,21 @@ class Standard
|
|
2113
2121
|
# set air loop availability controls and night cycle manager, after oa system added
|
2114
2122
|
air_loop.setAvailabilitySchedule(hvac_op_sch)
|
2115
2123
|
air_loop.setNightCycleControlType('CycleOnAny')
|
2116
|
-
|
2117
|
-
if
|
2118
|
-
avail_mgr =
|
2119
|
-
if avail_mgr.
|
2120
|
-
avail_mgr = avail_mgr.
|
2121
|
-
|
2122
|
-
|
2124
|
+
|
2125
|
+
if model.version < OpenStudio::VersionString.new('3.5.0')
|
2126
|
+
avail_mgr = air_loop.availabilityManager
|
2127
|
+
if avail_mgr.is_initialized
|
2128
|
+
avail_mgr = avail_mgr.get
|
2129
|
+
else
|
2130
|
+
avail_mgr = nil
|
2131
|
+
end
|
2132
|
+
else
|
2133
|
+
avail_mgr = air_loop.availabilityManagers[0]
|
2134
|
+
end
|
2135
|
+
|
2136
|
+
if !avail_mgr.nil? && avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
|
2137
|
+
avail_mgr = avail_mgr.to_AvailabilityManagerNightCycle.get
|
2138
|
+
avail_mgr.setCyclingRunTime(1800)
|
2123
2139
|
end
|
2124
2140
|
|
2125
2141
|
# attach the VAV system to each zone
|
@@ -2727,13 +2743,21 @@ class Standard
|
|
2727
2743
|
# set air loop availability controls and night cycle manager, after oa system added
|
2728
2744
|
air_loop.setAvailabilitySchedule(hvac_op_sch)
|
2729
2745
|
air_loop.setNightCycleControlType('CycleOnAny')
|
2730
|
-
|
2731
|
-
if
|
2732
|
-
avail_mgr =
|
2733
|
-
if avail_mgr.
|
2734
|
-
avail_mgr = avail_mgr.
|
2735
|
-
|
2736
|
-
|
2746
|
+
|
2747
|
+
if model.version < OpenStudio::VersionString.new('3.5.0')
|
2748
|
+
avail_mgr = air_loop.availabilityManager
|
2749
|
+
if avail_mgr.is_initialized
|
2750
|
+
avail_mgr = avail_mgr.get
|
2751
|
+
else
|
2752
|
+
avail_mgr = nil
|
2753
|
+
end
|
2754
|
+
else
|
2755
|
+
avail_mgr = air_loop.availabilityManagers[0]
|
2756
|
+
end
|
2757
|
+
|
2758
|
+
if !avail_mgr.nil? && avail_mgr.to_AvailabilityManagerNightCycle.is_initialized
|
2759
|
+
avail_mgr = avail_mgr.to_AvailabilityManagerNightCycle.get
|
2760
|
+
avail_mgr.setCyclingRunTime(1800)
|
2737
2761
|
end
|
2738
2762
|
|
2739
2763
|
# create a diffuser and attach the zone/diffuser pair to the air loop
|
@@ -3240,7 +3264,9 @@ class Standard
|
|
3240
3264
|
# To solve the issue, add economizer here for cold climates
|
3241
3265
|
# select the climate zones with winter design temperature lower than -20C (for safer)
|
3242
3266
|
cold_climates = ['ASHRAE 169-2006-6A', 'ASHRAE 169-2006-6B', 'ASHRAE 169-2006-7A',
|
3243
|
-
'ASHRAE 169-2006-7B', 'ASHRAE 169-2006-8A', 'ASHRAE 169-2006-8B'
|
3267
|
+
'ASHRAE 169-2006-7B', 'ASHRAE 169-2006-8A', 'ASHRAE 169-2006-8B',
|
3268
|
+
'ASHRAE 169-2013-6A', 'ASHRAE 169-2013-6B', 'ASHRAE 169-2013-7A',
|
3269
|
+
'ASHRAE 169-2013-7B', 'ASHRAE 169-2013-8A', 'ASHRAE 169-2013-8B']
|
3244
3270
|
if cold_climates.include? climate_zone
|
3245
3271
|
# Determine the economizer type in the prototype buildings, which depends on climate zone.
|
3246
3272
|
economizer_type = model_economizer_type(model, climate_zone)
|
@@ -5080,7 +5106,11 @@ class Standard
|
|
5080
5106
|
name: "#{air_loop.name} heating coil",
|
5081
5107
|
type: 'Residential Central Air Source HP',
|
5082
5108
|
cop: hspf_to_cop_heating_no_fan(hspf))
|
5083
|
-
|
5109
|
+
if model.version < OpenStudio::VersionString.new('3.5.0')
|
5110
|
+
htg_coil.setRatedSupplyFanPowerPerVolumeFlowRate(ac_w_per_cfm / OpenStudio.convert(1.0, 'cfm', 'm^3/s').get)
|
5111
|
+
else
|
5112
|
+
htg_coil.setRatedSupplyFanPowerPerVolumeFlowRate2017(ac_w_per_cfm / OpenStudio.convert(1.0, 'cfm', 'm^3/s').get)
|
5113
|
+
end
|
5084
5114
|
htg_coil.setMinimumOutdoorDryBulbTemperatureforCompressorOperation(OpenStudio.convert(min_hp_oat_f, 'F', 'C').get)
|
5085
5115
|
htg_coil.setMaximumOutdoorDryBulbTemperatureforDefrostOperation(OpenStudio.convert(40.0, 'F', 'C').get)
|
5086
5116
|
htg_coil.setCrankcaseHeaterCapacity(crank_case_heat_w)
|
@@ -1895,7 +1895,11 @@ class Standard
|
|
1895
1895
|
oa_system = air_loop_hvac.airLoopHVACOutdoorAirSystem.get
|
1896
1896
|
controller_oa = oa_system.getControllerOutdoorAir
|
1897
1897
|
controller_mv = controller_oa.controllerMechanicalVentilation
|
1898
|
-
|
1898
|
+
if air_loop_hvac.model.version < OpenStudio::VersionString.new('3.3.0')
|
1899
|
+
controller_mv.setSystemOutdoorAirMethod('VentilationRateProcedure')
|
1900
|
+
else
|
1901
|
+
controller_mv.setSystemOutdoorAirMethod('Standard62.1VentilationRateProcedureWithLimit')
|
1902
|
+
end
|
1899
1903
|
# Change the min flow rate in the controller outdoor air
|
1900
1904
|
controller_oa.setMinimumOutdoorAirFlowRate(0.0)
|
1901
1905
|
else
|
@@ -1924,6 +1928,16 @@ class Standard
|
|
1924
1928
|
end
|
1925
1929
|
end
|
1926
1930
|
|
1931
|
+
# Determine minimum ventilation efficiency for zones.
|
1932
|
+
# This is used to decrease the overall system minimum OA flow rate
|
1933
|
+
# such that a few zones do not drive the overall system OA flow rate too
|
1934
|
+
# high.
|
1935
|
+
def air_loop_hvac_minimum_zone_ventilation_efficiency(air_loop_hvac)
|
1936
|
+
min_ventilation_efficiency = 0.6
|
1937
|
+
|
1938
|
+
return min_ventilation_efficiency
|
1939
|
+
end
|
1940
|
+
|
1927
1941
|
# Set the minimum VAV damper positions.
|
1928
1942
|
#
|
1929
1943
|
# @param air_loop_hvac [OpenStudio::Model::AirLoopHVAC] air loop
|
@@ -529,7 +529,7 @@ class Standard
|
|
529
529
|
# Calculate the fenestration U-Factor base on the glass, frame,
|
530
530
|
# and divider performance and area calculated by EnergyPlus.
|
531
531
|
#
|
532
|
-
# @param [OpenStudio:Model:Construction]
|
532
|
+
# @param [OpenStudio:Model:Construction] OpenStudio Construction object
|
533
533
|
#
|
534
534
|
# @return [Double] the U-Factor in W/m^2*K
|
535
535
|
def construction_calculated_fenestration_u_factor_w_frame(construction)
|