openstudio-standards 0.2.17.rc1 → 0.2.17.rc2
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.SizingSystem.rb +9 -3
- data/lib/openstudio-standards/prototypes/common/objects/Prototype.hvac_systems.rb +50 -22
- 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.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 +8 -8
- data/lib/openstudio-standards/standards/ashrae_90_1/data/ashrae_90_1.parking.json +2 -2
- 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/version.rb +1 -1
- 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
|
|
@@ -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
|
@@ -5080,7 +5104,11 @@ class Standard
|
|
5080
5104
|
name: "#{air_loop.name} heating coil",
|
5081
5105
|
type: 'Residential Central Air Source HP',
|
5082
5106
|
cop: hspf_to_cop_heating_no_fan(hspf))
|
5083
|
-
|
5107
|
+
if model.version < OpenStudio::VersionString.new('3.5.0')
|
5108
|
+
htg_coil.setRatedSupplyFanPowerPerVolumeFlowRate(ac_w_per_cfm / OpenStudio.convert(1.0, 'cfm', 'm^3/s').get)
|
5109
|
+
else
|
5110
|
+
htg_coil.setRatedSupplyFanPowerPerVolumeFlowRate2017(ac_w_per_cfm / OpenStudio.convert(1.0, 'cfm', 'm^3/s').get)
|
5111
|
+
end
|
5084
5112
|
htg_coil.setMinimumOutdoorDryBulbTemperatureforCompressorOperation(OpenStudio.convert(min_hp_oat_f, 'F', 'C').get)
|
5085
5113
|
htg_coil.setMaximumOutdoorDryBulbTemperatureforDefrostOperation(OpenStudio.convert(40.0, 'F', 'C').get)
|
5086
5114
|
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)
|
@@ -19,21 +19,18 @@ class Standard
|
|
19
19
|
# @note Per 90.1, the Performance Rating Method "does NOT offer an alternative compliance path for minimum standard compliance."
|
20
20
|
# This means you can't use this method for code compliance to get a permit.
|
21
21
|
# @param user_model [OpenStudio::model::Model] User specified OpenStudio model
|
22
|
-
# @param building_type [String] the building type
|
23
22
|
# @param climate_zone [String] the climate zone
|
24
23
|
# @param hvac_building_type [String] the building type for baseline HVAC system determination (90.1-2016 and onward)
|
25
24
|
# @param wwr_building_type [String] the building type for baseline WWR determination (90.1-2016 and onward)
|
26
25
|
# @param swh_building_type [String] the building type for baseline SWH determination (90.1-2016 and onward)
|
27
|
-
# @param
|
28
|
-
# If nothing is specified, no custom logic will be applied; the process will follow the template logic explicitly.
|
29
|
-
# @param sizing_run_dir [String] the directory where the sizing runs will be performed
|
26
|
+
# @param output_dir [String] the directory where the PRM generations will be performed
|
30
27
|
# @param run_all_orients [Boolean] indicate weather a baseline model should be created for all 4 orientations: same as user model, +90 deg, +180 deg, +270 deg
|
31
28
|
# @param debug [Boolean] If true, will report out more detailed debugging output
|
32
29
|
# @return [Bool] returns true if successful, false if not
|
33
30
|
|
34
31
|
# Method used for 90.1-2016 and onward
|
35
|
-
def model_create_prm_stable_baseline_building(model,
|
36
|
-
model_create_prm_any_baseline_building(model,
|
32
|
+
def model_create_prm_stable_baseline_building(model, climate_zone, hvac_building_type, wwr_building_type, swh_building_type, output_dir = Dir.pwd, unmet_load_hours_check = true, debug = false)
|
33
|
+
model_create_prm_any_baseline_building(model, '', climate_zone, hvac_building_type, wwr_building_type, swh_building_type, true, false, output_dir, true, unmet_load_hours_check, debug)
|
37
34
|
end
|
38
35
|
|
39
36
|
# Creates a Performance Rating Method (aka Appendix G aka LEED) baseline building model
|
@@ -77,6 +74,9 @@ class Standard
|
|
77
74
|
OpenStudio.logFree(OpenStudio::Error, 'prm.log', "Proposed model unmet load hours exceed 300. Baseline model(s) won't be created.")
|
78
75
|
raise "Proposed model unmet load hours exceed 300. Baseline model(s) won't be created."
|
79
76
|
end
|
77
|
+
else
|
78
|
+
OpenStudio.logFree(OpenStudio::Error, 'prm.log', "Simulation failed. Check the model to make sure no severe errors.")
|
79
|
+
raise "Simulation on proposed model failed. Baseline generation is stopped."
|
80
80
|
end
|
81
81
|
end
|
82
82
|
|
@@ -1885,9 +1885,9 @@ class Standard
|
|
1885
1885
|
# separate the primary zones from the secondary zones.
|
1886
1886
|
# Add the baseline system type to the primary zones
|
1887
1887
|
# and add the suplemental system type to the secondary zones.
|
1888
|
-
story_zone_lists.each do |
|
1888
|
+
story_zone_lists.each do |story_group|
|
1889
1889
|
# Differentiate primary and secondary zones
|
1890
|
-
pri_sec_zone_lists = model_differentiate_primary_secondary_thermal_zones(model, story_group
|
1890
|
+
pri_sec_zone_lists = model_differentiate_primary_secondary_thermal_zones(model, story_group)
|
1891
1891
|
# Record the primary zone system types
|
1892
1892
|
pri_sec_zone_lists['primary'].each do |zone|
|
1893
1893
|
zone_to_sys_type[zone] = pri_system_type
|
@@ -6926,7 +6926,7 @@ class Standard
|
|
6926
6926
|
# include data source from:
|
6927
6927
|
# 1. user data csv files
|
6928
6928
|
# 2. data from measure and OpenStudio interface
|
6929
|
-
# @param [
|
6929
|
+
# @param [OpenStudio:model:Model] model
|
6930
6930
|
# @param [String] climate_zone
|
6931
6931
|
# @param [String] default_hvac_building_type
|
6932
6932
|
# @param [String] default_wwr_building_type
|
@@ -6940,7 +6940,7 @@ class Standard
|
|
6940
6940
|
# Template method for adding a setpoint manager for a coil control logic to a heating coil.
|
6941
6941
|
# ASHRAE 90.1-2019 Appendix G.
|
6942
6942
|
#
|
6943
|
-
# @param model [OpenStudio::Model::Model]
|
6943
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6944
6944
|
# @param thermalZones Array([OpenStudio::Model::ThermalZone]) thermal zone array
|
6945
6945
|
# @param coil Heating Coils
|
6946
6946
|
# @return [Boolean] true
|
@@ -6951,7 +6951,7 @@ class Standard
|
|
6951
6951
|
# Template method for adding zone additional property "zone DCV implemented in user model"
|
6952
6952
|
#
|
6953
6953
|
# @author Xuechen (Jerry) Lei, PNNL
|
6954
|
-
# @param model [OpenStudio::Model::Model]
|
6954
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6955
6955
|
def model_mark_zone_dcv_existence(model)
|
6956
6956
|
return true
|
6957
6957
|
end
|
@@ -6960,7 +6960,7 @@ class Standard
|
|
6960
6960
|
# The default shall be true
|
6961
6961
|
#
|
6962
6962
|
# @param [Boolean] run_all_orients: user inputs to indicate whether it is required to run all orientations
|
6963
|
-
# @param [OpenStudio::Model::Model]
|
6963
|
+
# @param [OpenStudio::Model::Model] OpenStudio model
|
6964
6964
|
def run_all_orientations(run_all_orients, user_model)
|
6965
6965
|
return run_all_orients
|
6966
6966
|
end
|
@@ -6968,7 +6968,7 @@ class Standard
|
|
6968
6968
|
# Template method for reading user data and adding to zone additional properties
|
6969
6969
|
#
|
6970
6970
|
# @author Xuechen (Jerry) Lei, PNNL
|
6971
|
-
# @param model [OpenStudio::Model::Model]
|
6971
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6972
6972
|
def model_add_dcv_user_exception_properties(model)
|
6973
6973
|
return true
|
6974
6974
|
end
|
@@ -6976,7 +6976,7 @@ class Standard
|
|
6976
6976
|
# Template method for raising user model DCV warning and errors
|
6977
6977
|
#
|
6978
6978
|
# @author Xuechen (Jerry) Lei, PNNL
|
6979
|
-
# @param model [OpenStudio::Model::Model]
|
6979
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6980
6980
|
def model_raise_user_model_dcv_errors(model)
|
6981
6981
|
return true
|
6982
6982
|
end
|
@@ -6984,7 +6984,7 @@ class Standard
|
|
6984
6984
|
# Template method for adding zone additional property "airloop dcv required by 901" and "zone dcv required by 901"
|
6985
6985
|
#
|
6986
6986
|
# @author Xuechen (Jerry) Lei, PNNL
|
6987
|
-
# @param model [OpenStudio::Model::Model]
|
6987
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6988
6988
|
def model_add_dcv_requirement_properties(model)
|
6989
6989
|
return true
|
6990
6990
|
end
|
@@ -6993,7 +6993,7 @@ class Standard
|
|
6993
6993
|
# Zone additional property 'apxg no need to have DCV' added
|
6994
6994
|
#
|
6995
6995
|
# @author Xuechen (Jerry) Lei, PNNL
|
6996
|
-
# @param model [OpenStudio::Model::Model]
|
6996
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
6997
6997
|
def model_add_apxg_dcv_properties(model)
|
6998
6998
|
return true
|
6999
6999
|
end
|
@@ -7001,14 +7001,14 @@ class Standard
|
|
7001
7001
|
# Template method for setting DCV in baseline HVAC system if required
|
7002
7002
|
#
|
7003
7003
|
# @author Xuechen (Jerry) Lei, PNNL
|
7004
|
-
# @param model [OpenStudio::Model::Model]
|
7004
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model
|
7005
7005
|
def model_set_baseline_demand_control_ventilation(model, climate_zone)
|
7006
7006
|
return true
|
7007
7007
|
end
|
7008
7008
|
|
7009
7009
|
# Identify the return air type associated with each thermal zone
|
7010
7010
|
#
|
7011
|
-
# @param model [OpenStudio::Model::Model]
|
7011
|
+
# @param model [OpenStudio::Model::Model] OpenStudio model object
|
7012
7012
|
def model_identify_return_air_type(model)
|
7013
7013
|
# air-loop based system
|
7014
7014
|
model.getThermalZones.each do |zone|
|
@@ -7,7 +7,7 @@ class Standard
|
|
7
7
|
# create a construction that meets those properties and assign it to this surface.
|
8
8
|
# 90.1-2007, 90.1-2010, 90.1-2013
|
9
9
|
#
|
10
|
-
# @param planar_surface [
|
10
|
+
# @param planar_surface [OpenStudio::Model:PlanarSurface] surface object
|
11
11
|
# @param climate_zone [String] ASHRAE climate zone, e.g. 'ASHRAE 169-2013-4A'
|
12
12
|
# @param previous_construction_map [Hash] a hash where the keys are an array of inputs
|
13
13
|
# [template, climate_zone, intended_surface_type, standards_construction_type, occ_type]
|
@@ -144,6 +144,7 @@ class Standard
|
|
144
144
|
# Zone HVAC operating schedule if providing ventilation
|
145
145
|
# Zone HVAC components return an OptionalSchedule object for supplyAirFanOperatingModeSchedule
|
146
146
|
# except for ZoneHVACTerminalUnitVariableRefrigerantFlow which returns a Schedule
|
147
|
+
# and starting at 3.5.0, PTAC / PTHP also return a Schedule, optional before that
|
147
148
|
existing_sch = nil
|
148
149
|
if zone_hvac_component.to_ZoneHVACFourPipeFanCoil.is_initialized
|
149
150
|
zone_hvac_component = zone_hvac_component.to_ZoneHVACFourPipeFanCoil.get
|
@@ -161,7 +162,7 @@ class Standard
|
|
161
162
|
ventilation = true if oa_rate > 0.0
|
162
163
|
end
|
163
164
|
ventilation = true if zone_hvac_component.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized
|
164
|
-
fan_op_sch = zone_hvac_component.supplyAirFanOperatingModeSchedule
|
165
|
+
fan_op_sch = OpenStudio::Model::OptionalSchedule.new(zone_hvac_component.supplyAirFanOperatingModeSchedule)
|
165
166
|
existing_sch = fan_op_sch.get if fan_op_sch.is_initialized
|
166
167
|
elsif zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.is_initialized
|
167
168
|
zone_hvac_component = zone_hvac_component.to_ZoneHVACPackagedTerminalHeatPump.get
|
@@ -170,7 +171,7 @@ class Standard
|
|
170
171
|
ventilation = true if oa_rate > 0.0
|
171
172
|
end
|
172
173
|
ventilation = true if zone_hvac_component.isOutdoorAirFlowRateWhenNoCoolingorHeatingisNeededAutosized
|
173
|
-
fan_op_sch = zone_hvac_component.supplyAirFanOperatingModeSchedule
|
174
|
+
fan_op_sch = OpenStudio::Model::OptionalSchedule.new(zone_hvac_component.supplyAirFanOperatingModeSchedule)
|
174
175
|
existing_sch = fan_op_sch.get if fan_op_sch.is_initialized
|
175
176
|
elsif zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.is_initialized
|
176
177
|
zone_hvac_component = zone_hvac_component.to_ZoneHVACTerminalUnitVariableRefrigerantFlow.get
|