openstudio-standards 0.2.0.rc1 → 0.2.0.rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (23) hide show
  1. checksums.yaml +4 -4
  2. data/data/standards/export_OpenStudio_libraries.rb +392 -376
  3. data/data/standards/manage_OpenStudio_Standards.rb +0 -1
  4. data/lib/openstudio-standards/btap/fileio.rb +0 -1
  5. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.Hospital.rb +2 -2
  6. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.LargeHotel.rb +2 -2
  7. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.PrimarySchool.rb +2 -2
  8. data/lib/openstudio-standards/prototypes/common/buildings/Prototype.SecondarySchool.rb +2 -2
  9. data/lib/openstudio-standards/refs/references.rb +13 -0
  10. data/lib/openstudio-standards/standards/Standards.Construction.rb +6 -6
  11. data/lib/openstudio-standards/standards/Standards.Model.rb +1 -1
  12. data/lib/openstudio-standards/standards/Standards.Pump.rb +18 -7
  13. data/lib/openstudio-standards/standards/Standards.ScheduleRuleset.rb +2 -2
  14. data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +7 -7
  15. data/lib/openstudio-standards/standards/icc_iecc/icc_iecc.rb +9 -0
  16. data/lib/openstudio-standards/standards/icc_iecc/icc_iecc_2015/icc_iecc_2015.rb +16 -0
  17. data/lib/openstudio-standards/standards/necb/necb_2011/necb_2011.rb +0 -1
  18. data/lib/openstudio-standards/standards/necb/necb_2015/necb_2015.rb +0 -1
  19. data/lib/openstudio-standards/standards/oeesc/oeesc.rb +9 -0
  20. data/lib/openstudio-standards/standards/oeesc/oeesc_2014/oeesc_2014.rb +16 -0
  21. data/lib/openstudio-standards/version.rb +1 -1
  22. data/lib/openstudio-standards.rb +6 -0
  23. metadata +8 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: a78c7667ff57212581bbc69d8744490c265aff07
4
- data.tar.gz: b107d9d448db0c835b05bacb73ba5bc56ca3d51b
3
+ metadata.gz: 7971c760a2256abb5458a28ad4e0d31a9364acca
4
+ data.tar.gz: b4ed3ac1b33749ad8511de8b22dac45052074476
5
5
  SHA512:
6
- metadata.gz: 27fa35de23af880319a26fff22651e1f537eb552fda5a94a09f2a47fd4c5eed354138993b5eb90cdb6621b6b7cd146f721f751dd0441d15df71b036f272d6b5b
7
- data.tar.gz: d15cce110d43968f18d4374b3b3144606c3b1aabb88f1ee328431e2ccfee4b2b4f50b72621a2817dd123f9fb4bb89bf0da0478934a500a4aad5b2a79d0529e40
6
+ metadata.gz: 7156d8390581e7633b5ec60a0fb1d44f8bb1eb78876eaf5b4ab26adcddededd0fe2b5e6a3e411d1721cce3532e5cb1c7d108f54ccfe00148555fb42b97502055
7
+ data.tar.gz: 8a8c9b87d8796999ffcee7319ec59f109513f5a7ed2057ac1b5853936263781a78797febee97909888af385c51a3db17d92a2b7402843299d9e63cf78b238f5d
@@ -10,14 +10,15 @@ require 'openstudio'
10
10
  require_relative '../../lib/openstudio-standards'
11
11
 
12
12
  def export_openstudio_libraries
13
+ start_time = Time.now
13
14
 
14
15
  ### Define what to include in the libraries ###
15
- include_construction_sets = true # Construction Sets, Constructions, and Materials
16
- include_space_types = true # Space Types, Internal Loads, and associated Schedule Sets and Schedules
17
16
  include_boilers = true # BoilerHotWater
18
17
  include_chillers = true # ChillerElectricEIR
19
18
  include_unitary_acs = true # CoilCoolingDXSingleSpeed
20
- include_heat_pumps = true # CoilCoolingDXSingleSpeed, CoilHeatingDXSingleSpeed, AirLoopHVACUnitaryHeatPump
19
+ include_heat_pumps = false # CoilCoolingDXSingleSpeed, CoilHeatingDXSingleSpeed, AirLoopHVACUnitaryHeatPump
20
+ include_space_types = true # Space Types, Internal Loads, and associated Schedule Sets and Schedules
21
+ include_construction_sets = true # Construction Sets, Constructions, and Materials
21
22
 
22
23
  # Make an initial Standard to access the library data
23
24
  std = Standard.build('90.1-2013')
@@ -27,412 +28,427 @@ def export_openstudio_libraries
27
28
  templates_to_climate_zones = JSON.parse(temp)
28
29
 
29
30
  # Make a library model for each template
30
- template_to_lib_models = {}
31
31
  std.standards_data["templates"].each do |template|
32
- template_name = template['name']
33
- data = {}
34
- data['model'] = OpenStudio::Model::Model.new
32
+
33
+ # Wrap each library creation in a begin/rescue because
34
+ # the entire process can take a long time and
35
+ # we don't want to lose all templates if one fails
35
36
  begin
36
- data['standard_applier'] = Standard.build(template_name)
37
- template_to_lib_models[template_name] = data
38
- rescue Exception => e
39
- puts "'#{template_name}' is not defined in OpenStudio-Standards yet"
40
- end
41
- end
42
37
 
43
- # Construction Sets, Constructions, and Materials
44
- # TODO fix code to remove duplicate constructions and materials
45
- if include_construction_sets
46
- std.standards_data['construction_sets'].each do |props|
47
- lib = template_to_lib_models[props['template']]
48
- next if lib.nil? # Skip unsupported templates
49
- model = lib['model']
50
- std_applier = lib['standard_applier']
51
-
52
- # Add a construction set for each valid climate zone
53
- templates_to_climate_zones[props['template']].each do |climate_zone|
54
- construction_set = std_applier.model_add_construction_set(model,
55
- climate_zone,
56
- props['building_type'],
57
- props['space_type'],
58
- props['is_residential'])
38
+ # Make a Standard for this template
39
+ template_name = template['name']
40
+ puts "*** Making #{template_name} ***"
41
+ template_start_time = Time.now
42
+ puts "* Started #{template_name} at: #{template_start_time}"
43
+ begin
44
+ std_applier = Standard.build(template_name)
45
+ rescue Exception => e
46
+ puts "'#{template_name}' is not defined in OpenStudio-Standards yet"
59
47
  end
60
- end
61
- end
62
-
63
- # Space Types
64
- if include_space_types
65
- std.standards_data['space_types'].each do |props|
66
- lib = template_to_lib_models[props['template']]
67
- next if lib.nil? # Skip unsupported templates
68
- model = lib['model']
69
- std_applier = lib['standard_applier']
70
48
 
71
- # Create a new space type
72
- space_type = OpenStudio::Model::SpaceType.new(model)
73
- space_type.setStandardsBuildingType(props['building_type'])
74
- space_type.setStandardsSpaceType(props['space_type'])
75
- space_type.setName("#{props['building_type']} #{props['space_type']}")
49
+ # Reset the openstudio-standards log
50
+ reset_log
51
+
52
+ next unless template_name == '90.1-2004'
53
+
54
+ # Make an empty model
55
+ model = OpenStudio::Model::Model.new
56
+
57
+ # Boilers
58
+ if include_boilers
59
+ puts "* Boilers *"
60
+ std.standards_data['boilers'].each do |props|
61
+ next unless props['template'] == template_name
62
+
63
+ # Make a new boiler
64
+ boiler = OpenStudio::Model::BoilerHotWater.new(model)
65
+ # Fuel Type
66
+ case props['fuel_type']
67
+ when 'Gas'
68
+ boiler.setFuelType('NaturalGas')
69
+ when 'Electric'
70
+ boiler.setFuelType('Electricity')
71
+ when 'Oil'
72
+ boiler.setFuelType('FuelOil#2')
73
+ end
74
+ # Set capacity to middle of range
75
+ min_cap_btu_per_hr = props['minimum_capacity'].to_f
76
+ max_cap_btu_per_hr = props['maximum_capacity'].to_f
77
+ mid_cap_btu_per_hr = (min_cap_btu_per_hr + max_cap_btu_per_hr) / 2
78
+ mid_cap_w = OpenStudio.convert(mid_cap_btu_per_hr, 'Btu/hr', 'W').get
79
+ boiler.setNominalCapacity(mid_cap_w)
80
+
81
+ # Apply the standard
82
+ std_applier.boiler_hot_water_apply_efficiency_and_curves(boiler)
83
+
84
+ # Reset the capacity
85
+ boiler.autosizeNominalCapacity
86
+
87
+ # Modify the name of the boiler to reflect the capacity range
88
+ min_cap_kbtu_per_hr = OpenStudio.convert(min_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
89
+ max_cap_kbtu_per_hr = OpenStudio.convert(max_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
90
+
91
+ old_name = boiler.name.get.to_s
92
+ m = old_name.match(/(\d+)kBtu\/hr/)
93
+ if m
94
+ # Put the fuel type into the name
95
+ old_type = 'Boiler Hot Water 1'
96
+ new_type = "#{props['fuel_type']} Boiler"
97
+ new_name = old_name.gsub(old_type, new_type)
98
+ # Swap out the capacity number for a range
99
+ old_cap = m[1]
100
+ if max_cap_kbtu_per_hr == 10_000_000 # Value representing infinity
101
+ new_cap = "> #{min_cap_kbtu_per_hr}"
102
+ else
103
+ new_cap = "#{min_cap_kbtu_per_hr}-#{max_cap_kbtu_per_hr}"
104
+ end
105
+ new_name = new_name.gsub(old_cap, new_cap)
106
+ boiler.setName(new_name)
107
+ puts "#{props['template']}: #{boiler.name.get.to_s}"
108
+ end
76
109
 
77
- # Rendering color
78
- std_applier.space_type_apply_rendering_color(space_type)
79
-
80
- # Loads
81
- std_applier.space_type_apply_internal_loads(space_type, true, true, true, true, true, true)
110
+ end
111
+ end
82
112
 
83
- # Schedules
84
- std_applier.space_type_apply_internal_load_schedules(space_type, true, true, true, true, true, true, true)
113
+ # Chillers
114
+ if include_chillers
115
+ puts "* Chillers *"
116
+ std.standards_data['chillers'].each do |props|
117
+ next unless props['template'] == template_name
118
+
119
+ # Skip absorption chillers
120
+ next unless props['absorption_type'].nil?
121
+
122
+ # Skip interim chiller efficiency requirements
123
+ next unless props['end_date'] == "2999-09-09T00:00:00+00:00"
124
+
125
+ # Make a new chiller
126
+ chiller = OpenStudio::Model::ChillerElectricEIR.new(model)
127
+ # Set capacity to middle of range
128
+ min_cap_tons = props['minimum_capacity'].to_f
129
+ max_cap_tons = props['maximum_capacity'].to_f
130
+ mid_cap_tons = (min_cap_tons + max_cap_tons) / 2
131
+ mid_cap_w = OpenStudio.convert(mid_cap_tons, 'ton', 'W').get
132
+ chiller.setReferenceCapacity(mid_cap_w)
133
+
134
+ # Add the chiller properties to the name, because this is what
135
+ # the standards currently work off of.
136
+ if props['cooling_type'] == 'AirCooled'
137
+ new_name = "#{props['cooling_type']} Chiller #{props['condenser_type']}"
138
+ elsif props['cooling_type'] == 'WaterCooled'
139
+ new_name = "#{props['cooling_type']} #{props['compressor_type']} Chiller"
140
+ else
141
+ new_name = chiller.name.get
142
+ end
143
+ chiller.setName(new_name)
144
+
145
+ # Apply the standard
146
+ std_applier.chiller_electric_eir_apply_efficiency_and_curves(chiller, nil)
147
+
148
+ # Reset the capacity
149
+ chiller.autosizeReferenceCapacity
150
+
151
+ # Modify the name of the chiller to reflect the capacity range
152
+ old_name = chiller.name.get.to_s
153
+ m = old_name.match(/(\d+)tons/)
154
+ if m
155
+ # Put the fuel type into the name
156
+ old_type = 'Chiller Electric EIR 1'
157
+ new_type = 'Chiller'
158
+ new_name = old_name.gsub(old_type, new_type)
159
+ # Swap out the capacity number for a range
160
+ old_cap = m[1]
161
+ if max_cap_tons == 10_000 # Value representing infinity
162
+ new_cap = "> #{min_cap_tons.round}"
163
+ else
164
+ new_cap = "#{min_cap_tons.round}-#{max_cap_tons.round}"
165
+ end
166
+ new_name = new_name.gsub(old_cap, new_cap)
167
+ chiller.setName(new_name)
168
+ puts "#{props['template']}: #{chiller.name.get.to_s}"
169
+ end
85
170
 
86
- end
87
- end
88
-
89
- # Boilers
90
- if include_boilers
91
- std.standards_data['boilers'].each do |props|
92
- lib = template_to_lib_models[props['template']]
93
- next if lib.nil? # Skip unsupported templates
94
- # Skip NECB 2011 for now
95
- next if props['template'] == 'NECB 2011'
96
- model = lib['model']
97
- std_applier = lib['standard_applier']
98
-
99
- # Make a new boiler
100
- boiler = OpenStudio::Model::BoilerHotWater.new(model)
101
- # Fuel Type
102
- case props['fuel_type']
103
- when 'Gas'
104
- boiler.setFuelType('NaturalGas')
105
- when 'Electric'
106
- boiler.setFuelType('Electricity')
107
- when 'Oil'
108
- boiler.setFuelType('FuelOil#2')
109
- end
110
- # Set capacity to middle of range
111
- min_cap_btu_per_hr = props['minimum_capacity'].to_f
112
- max_cap_btu_per_hr = props['maximum_capacity'].to_f
113
- mid_cap_btu_per_hr = (min_cap_btu_per_hr + max_cap_btu_per_hr) / 2
114
- mid_cap_w = OpenStudio.convert(mid_cap_btu_per_hr, 'Btu/hr', 'W').get
115
- boiler.setNominalCapacity(mid_cap_w)
116
-
117
- # Apply the standard
118
- std_applier.boiler_hot_water_apply_efficiency_and_curves(boiler)
119
-
120
- # Reset the capacity
121
- boiler.autosizeNominalCapacity
122
-
123
- # Modify the name of the boiler to reflect the capacity range
124
- min_cap_kbtu_per_hr = OpenStudio.convert(min_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
125
- max_cap_kbtu_per_hr = OpenStudio.convert(max_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
126
-
127
- old_name = boiler.name.get.to_s
128
- m = old_name.match(/(\d+)kBtu\/hr/)
129
- if m
130
- # Put the fuel type into the name
131
- old_type = 'Boiler Hot Water 1'
132
- new_type = "#{props['fuel_type']} Boiler"
133
- new_name = old_name.gsub(old_type, new_type)
134
- # Swap out the capacity number for a range
135
- old_cap = m[1]
136
- if max_cap_kbtu_per_hr == 10_000_000 # Value representing infinity
137
- new_cap = "> #{min_cap_kbtu_per_hr}"
138
- else
139
- new_cap = "#{min_cap_kbtu_per_hr}-#{max_cap_kbtu_per_hr}"
140
171
  end
141
- new_name = new_name.gsub(old_cap, new_cap)
142
- boiler.setName(new_name)
143
- puts "#{props['template']}: #{boiler.name.get.to_s}"
144
172
  end
145
173
 
146
- end
147
- end
174
+ # Unitary AC
175
+ if include_unitary_acs
176
+ puts "* Unitary ACs *"
177
+ std.standards_data['unitary_acs'].each do |props|
178
+ next unless props['template'] == template_name
179
+
180
+ # Skip interim efficiency requirements
181
+ next unless props['end_date'] == "2999-09-09T00:00:00+00:00"
182
+
183
+ # Make a new DX coil
184
+ dx_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model)
185
+ # Set capacity to middle of range
186
+ min_cap_btu_per_hr = props['minimum_capacity'].to_f
187
+ max_cap_btu_per_hr = props['maximum_capacity'].to_f
188
+ mid_cap_btu_per_hr = (min_cap_btu_per_hr + max_cap_btu_per_hr) / 2
189
+ mid_cap_w = OpenStudio.convert(mid_cap_btu_per_hr, 'Btu/hr', 'W').get
190
+ dx_coil.setRatedTotalCoolingCapacity(mid_cap_w)
191
+
192
+ # Add the subcategory to the name so that it
193
+ # can be used by the efficiency lookup
194
+ dx_coil.setName("#{dx_coil.name} #{props['subcategory']}")
195
+
196
+ # If it is a PTAC coil, add to PTAC
197
+ if props['subcategory'] == 'PTAC'
198
+ htg_coil = nil
199
+ if props['heating_type'] == 'Electric Resistance or None'
200
+ htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model)
201
+ htg_coil.setName('PTAC Electric Backup Htg Coil')
202
+ else
203
+ htg_coil = OpenStudio::Model::CoilHeatingGas.new(model)
204
+ htg_coil.setName('PTAC Gas Backup Htg Coil')
205
+ end
206
+ fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
207
+ fan.setName("PTAC Supply Fan")
208
+ ptac = OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner.new(model,
209
+ model.alwaysOnDiscreteSchedule,
210
+ fan,
211
+ htg_coil,
212
+ dx_coil)
213
+ end
214
+
215
+ # Apply the standard
216
+ std_applier.coil_cooling_dx_single_speed_apply_efficiency_and_curves(dx_coil, {})
217
+
218
+ # Reset the capacity
219
+ dx_coil.autosizeRatedTotalCoolingCapacity
220
+
221
+ # Modify the name of the boiler to reflect the capacity range
222
+ min_cap_kbtu_per_hr = OpenStudio.convert(min_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
223
+ max_cap_kbtu_per_hr = OpenStudio.convert(max_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
224
+
225
+ # Modify the name of the dx_coil to reflect the capacity range
226
+ old_name = dx_coil.name.get.to_s
227
+ m = old_name.match(/(\d+)kBtu\/hr/)
228
+ if m
229
+ # Put the fuel type into the name
230
+ old_type = "Coil Cooling DX Single Speed 1 #{props['subcategory']}"
231
+ new_type = "#{props['cooling_type']} #{props['heating_type']} #{props['subcategory']} DX"
232
+ new_name = old_name.gsub(old_type, new_type)
233
+ # Swap out the capacity number for a range
234
+ old_cap = m[1]
235
+ if max_cap_kbtu_per_hr == 10_000 # Value representing infinity
236
+ new_cap = "> #{min_cap_kbtu_per_hr}"
237
+ else
238
+ new_cap = "#{min_cap_kbtu_per_hr}-#{max_cap_kbtu_per_hr}"
239
+ end
240
+ new_name = new_name.gsub(old_cap, new_cap)
241
+ dx_coil.setName(new_name)
242
+ puts "#{props['template']}: #{dx_coil.name.get.to_s}"
243
+
244
+ # Rename PTAC too
245
+ if props['subcategory'] == 'PTAC'
246
+ ptac.setName("PTAC #{new_name}")
247
+ end
248
+
249
+ end
148
250
 
149
- # Chillers
150
- if include_chillers
151
- std.standards_data['chillers'].each do |props|
152
- lib = template_to_lib_models[props['template']]
153
- next if lib.nil? # Skip unsupported templates
154
- # Skip NECB 2011 for now
155
- next if props['template'] == 'NECB 2011'
156
- model = lib['model']
157
- std_applier = lib['standard_applier']
158
-
159
- # Skip absorption chillers
160
- next unless props['absorption_type'].nil?
161
-
162
- # Skip interim chiller efficiency requirements
163
- next unless props['end_date'] == "2999-09-09T00:00:00+00:00"
164
-
165
- # Make a new chiller
166
- chiller = OpenStudio::Model::ChillerElectricEIR.new(model)
167
- # Set capacity to middle of range
168
- min_cap_tons = props['minimum_capacity'].to_f
169
- max_cap_tons = props['maximum_capacity'].to_f
170
- mid_cap_tons = (min_cap_tons + max_cap_tons) / 2
171
- mid_cap_w = OpenStudio.convert(mid_cap_tons, 'ton', 'W').get
172
- chiller.setReferenceCapacity(mid_cap_w)
173
-
174
- # Add the chiller properties to the name, because this is what
175
- # the standards currently work off of.
176
- if props['cooling_type'] == 'AirCooled'
177
- new_name = "#{props['cooling_type']} Chiller #{props['condenser_type']}"
178
- elsif props['cooling_type'] == 'WaterCooled'
179
- new_name = "#{props['cooling_type']} #{props['compressor_type']} Chiller"
180
- else
181
- new_name = chiller.name.get
182
- end
183
- chiller.setName(new_name)
184
-
185
- # Apply the standard
186
- std_applier.chiller_electric_eir_apply_efficiency_and_curves(chiller, nil)
187
-
188
- # Reset the capacity
189
- chiller.autosizeReferenceCapacity
190
-
191
- # Modify the name of the chiller to reflect the capacity range
192
- old_name = chiller.name.get.to_s
193
- m = old_name.match(/(\d+)tons/)
194
- if m
195
- # Put the fuel type into the name
196
- old_type = 'Chiller Electric EIR 1'
197
- new_type = 'Chiller'
198
- new_name = old_name.gsub(old_type, new_type)
199
- # Swap out the capacity number for a range
200
- old_cap = m[1]
201
- if max_cap_tons == 10_000 # Value representing infinity
202
- new_cap = "> #{min_cap_tons.round}"
203
- else
204
- new_cap = "#{min_cap_tons.round}-#{max_cap_tons.round}"
205
251
  end
206
- new_name = new_name.gsub(old_cap, new_cap)
207
- chiller.setName(new_name)
208
- puts "#{props['template']}: #{chiller.name.get.to_s}"
209
252
  end
210
253
 
211
- end
212
- end
254
+ # Heat Pumps
255
+ if include_heat_pumps
256
+ puts "* Heat Pumps *"
257
+ std.standards_data['heat_pumps'].each do |props|
258
+ next unless props['template'] == template_name
259
+
260
+ # Skip interim efficiency requirements
261
+ next unless props['end_date'] == "2999-09-09T00:00:00+00:00"
262
+
263
+ # Make a new DX cooling coil
264
+ clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model)
265
+ # Set capacity to middle of range
266
+ min_clg_cap_btu_per_hr = props['minimum_capacity'].to_f
267
+ max_clg_cap_btu_per_hr = props['maximum_capacity'].to_f
268
+ mid_clg_cap_btu_per_hr = (min_clg_cap_btu_per_hr + max_clg_cap_btu_per_hr) / 2
269
+ mid_clg_cap_w = OpenStudio.convert(mid_clg_cap_btu_per_hr, 'Btu/hr', 'W').get
270
+ clg_coil.setRatedTotalCoolingCapacity(mid_clg_cap_w)
271
+
272
+ # Make a new DX heating coil sized at 90% of the capacity
273
+ # of the cooling coil.
274
+ htg_coil = OpenStudio::Model::CoilHeatingDXSingleSpeed.new(model)
275
+ mid_htg_cap_w = mid_clg_cap_w * 0.9
276
+ htg_coil.setRatedTotalHeatingCapacity(mid_htg_cap_w)
277
+
278
+ # If it is a PTHP Coil, add to PTHP
279
+ # If not, add to unitary HP
280
+ if props['subcategory'] == 'PTHP'
281
+ if props['heating_type'] == 'Electric Resistance or None'
282
+ backup_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model)
283
+ backup_htg_coil.setName('PTHP Electric Backup Htg Coil')
284
+ else
285
+ backup_htg_coil = OpenStudio::Model::CoilHeatingGas.new(model)
286
+ backup_htg_coil.setName('PTHP Electric Backup Htg Coil')
287
+ end
288
+ fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
289
+ fan.setName("PTHP Supply Fan")
290
+ pthp = OpenStudio::Model::ZoneHVACPackagedTerminalHeatPump.new(model,
291
+ model.alwaysOnDiscreteSchedule,
292
+ fan,
293
+ htg_coil,
294
+ clg_coil,
295
+ backup_htg_coil)
296
+ else
297
+ if props['heating_type'] == 'Electric Resistance or None'
298
+ backup_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model)
299
+ backup_htg_coil.setName('Unitary Heat Pump Electric Backup Htg Coil')
300
+ else
301
+ backup_htg_coil = OpenStudio::Model::CoilHeatingGas.new(model)
302
+ backup_htg_coil.setName('Unitary Heat Pump Electric Backup Htg Coil')
303
+ end
304
+ fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
305
+ fan.setName("Unitary Heat Pump Supply Fan")
306
+ unitary_system = OpenStudio::Model::AirLoopHVACUnitaryHeatPumpAirToAir.new(model,
307
+ model.alwaysOnDiscreteSchedule,
308
+ fan,
309
+ htg_coil,
310
+ clg_coil,
311
+ backup_htg_coil)
312
+ unitary_system.setName("Unitary Heat Pump")
313
+ unitary_system.setMaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation(OpenStudio.convert(40, 'F', 'C').get)
314
+ end
315
+
316
+ # Apply the standard
317
+ std_applier.coil_cooling_dx_single_speed_apply_efficiency_and_curves(clg_coil, {})
318
+ std_applier.coil_heating_dx_single_speed_apply_efficiency_and_curves(htg_coil, {})
319
+
320
+ # Reset the capacity
321
+ clg_coil.autosizeRatedTotalCoolingCapacity
322
+ htg_coil.autosizeRatedTotalHeatingCapacity
323
+
324
+ # Modify the name of the boiler to reflect the capacity range
325
+ min_clg_cap_kbtu_per_hr = OpenStudio.convert(min_clg_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
326
+ max_clg_cap_kbtu_per_hr = OpenStudio.convert(max_clg_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
327
+
328
+ # Modify the name of the dx_coil to reflect the capacity range
329
+ old_name = clg_coil.name.get.to_s
330
+ m = old_name.match(/(\d+)kBtu\/hr/)
331
+ if m
332
+ # Put the fuel type into the name
333
+ old_type = 'Coil Cooling DX Single Speed 1'
334
+ new_type = "#{props['cooling_type']} #{props['heating_type']} #{props['subcategory']} DX"
335
+ new_name = old_name.gsub(old_type, new_type)
336
+ # Swap out the capacity number for a range
337
+ old_cap = m[1]
338
+ if max_clg_cap_kbtu_per_hr == 10_000 # Value representing infinity
339
+ new_cap = "> #{min_clg_cap_kbtu_per_hr}"
340
+ else
341
+ new_cap = "#{min_clg_cap_kbtu_per_hr}-#{max_clg_cap_kbtu_per_hr}"
342
+ end
343
+ new_name = new_name.gsub(old_cap, new_cap)
344
+ clg_coil.setName(new_name)
345
+ puts "#{props['template']}: #{clg_coil.name.get.to_s}"
346
+
347
+ # Rename PTHP or unitary same as the cooling coil
348
+ if pthp
349
+ pthp.setName("PTHP #{new_name}")
350
+ else
351
+ unitary_system.setName("Unitary Heat Pump #{new_name}")
352
+ end
353
+
354
+ # Rename the heating coil
355
+ old_type = 'Coil Heating DX Single Speed 1'
356
+ new_type = "#{props['cooling_type']} #{props['heating_type']} #{props['subcategory']} DX"
357
+ new_name = old_name.gsub(old_type, new_type)
358
+ # Swap out the capacity number for a blank
359
+ old_cap = m[1]
360
+ new_name = new_name.gsub(old_cap, '')
361
+ htg_coil.setName(new_name)
362
+
363
+ end
213
364
 
214
- # Unitary AC
215
- if include_unitary_acs
216
- std.standards_data['unitary_acs'].each do |props|
217
- lib = template_to_lib_models[props['template']]
218
- next if lib.nil? # Skip unsupported templates
219
- # Skip NECB 2011 for now
220
- next if props['template'] == 'NECB 2011'
221
- model = lib['model']
222
- std_applier = lib['standard_applier']
223
-
224
- # Skip interim efficiency requirements
225
- next unless props['end_date'] == "2999-09-09T00:00:00+00:00"
226
-
227
- # Make a new DX coil
228
- dx_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model)
229
- # Set capacity to middle of range
230
- min_cap_btu_per_hr = props['minimum_capacity'].to_f
231
- max_cap_btu_per_hr = props['maximum_capacity'].to_f
232
- mid_cap_btu_per_hr = (min_cap_btu_per_hr + max_cap_btu_per_hr) / 2
233
- mid_cap_w = OpenStudio.convert(mid_cap_btu_per_hr, 'Btu/hr', 'W').get
234
- dx_coil.setRatedTotalCoolingCapacity(mid_cap_w)
235
-
236
- # Add the subcategory to the name so that it
237
- # can be used by the efficiency lookup
238
- dx_coil.setName("#{dx_coil.name} #{props['subcategory']}")
239
-
240
- # If it is a PTAC coil, add to PTAC
241
- if props['subcategory'] == 'PTAC'
242
- htg_coil = nil
243
- if props['heating_type'] == 'Electric Resistance or None'
244
- htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model)
245
- htg_coil.setName('PTAC Electric Backup Htg Coil')
246
- else
247
- htg_coil = OpenStudio::Model::CoilHeatingGas.new(model)
248
- htg_coil.setName('PTAC Gas Backup Htg Coil')
249
365
  end
250
- fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
251
- fan.setName("PTAC Supply Fan")
252
- ptac = OpenStudio::Model::ZoneHVACPackagedTerminalAirConditioner.new(model,
253
- model.alwaysOnDiscreteSchedule,
254
- fan,
255
- htg_coil,
256
- dx_coil)
257
366
  end
258
367
 
259
- # Apply the standard
260
- std_applier.coil_cooling_dx_single_speed_apply_efficiency_and_curves(dx_coil, {})
261
-
262
- # Reset the capacity
263
- dx_coil.autosizeRatedTotalCoolingCapacity
264
-
265
- # Modify the name of the boiler to reflect the capacity range
266
- min_cap_kbtu_per_hr = OpenStudio.convert(min_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
267
- max_cap_kbtu_per_hr = OpenStudio.convert(max_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
268
-
269
- # Modify the name of the dx_coil to reflect the capacity range
270
- old_name = dx_coil.name.get.to_s
271
- m = old_name.match(/(\d+)kBtu\/hr/)
272
- if m
273
- # Put the fuel type into the name
274
- old_type = "Coil Cooling DX Single Speed 1 #{props['subcategory']}"
275
- new_type = "#{props['cooling_type']} #{props['heating_type']} #{props['subcategory']} DX"
276
- new_name = old_name.gsub(old_type, new_type)
277
- # Swap out the capacity number for a range
278
- old_cap = m[1]
279
- if max_cap_kbtu_per_hr == 10_000 # Value representing infinity
280
- new_cap = "> #{min_cap_kbtu_per_hr}"
281
- else
282
- new_cap = "#{min_cap_kbtu_per_hr}-#{max_cap_kbtu_per_hr}"
283
- end
284
- new_name = new_name.gsub(old_cap, new_cap)
285
- dx_coil.setName(new_name)
286
- puts "#{props['template']}: #{dx_coil.name.get.to_s}"
368
+ # Space Types
369
+ if include_space_types
370
+ puts "* Space Types *"
371
+ std.standards_data['space_types'].each do |props|
372
+ next unless props['template'] == template_name
287
373
 
288
- # Rename PTAC too
289
- if props['subcategory'] == 'PTAC'
290
- ptac.setName("PTAC #{new_name}")
291
- end
374
+ # Create a new space type
375
+ space_type = OpenStudio::Model::SpaceType.new(model)
376
+ space_type.setStandardsBuildingType(props['building_type'])
377
+ space_type.setStandardsSpaceType(props['space_type'])
378
+ space_type.setName("#{props['building_type']} #{props['space_type']}")
292
379
 
293
- end
380
+ # Rendering color
381
+ std_applier.space_type_apply_rendering_color(space_type)
294
382
 
295
- end
296
- end
383
+ # Loads
384
+ std_applier.space_type_apply_internal_loads(space_type, true, true, true, true, true, true)
385
+
386
+ # Schedules
387
+ std_applier.space_type_apply_internal_load_schedules(space_type, true, true, true, true, true, true, true)
297
388
 
298
- # Heat Pumps
299
- if include_heat_pumps
300
- std.standards_data['heat_pumps'].each do |props|
301
- lib = template_to_lib_models[props['template']]
302
- next if lib.nil? # Skip unsupported templates
303
- # Skip NECB 2011 for now
304
- next if props['template'] == 'NECB 2011'
305
- model = lib['model']
306
- std_applier = lib['standard_applier']
307
-
308
- # Skip interim efficiency requirements
309
- next unless props['end_date'] == "2999-09-09T00:00:00+00:00"
310
-
311
- # Make a new DX cooling coil
312
- clg_coil = OpenStudio::Model::CoilCoolingDXSingleSpeed.new(model)
313
- # Set capacity to middle of range
314
- min_clg_cap_btu_per_hr = props['minimum_capacity'].to_f
315
- max_clg_cap_btu_per_hr = props['maximum_capacity'].to_f
316
- mid_clg_cap_btu_per_hr = (min_clg_cap_btu_per_hr + max_clg_cap_btu_per_hr) / 2
317
- mid_clg_cap_w = OpenStudio.convert(mid_clg_cap_btu_per_hr, 'Btu/hr', 'W').get
318
- clg_coil.setRatedTotalCoolingCapacity(mid_clg_cap_w)
319
-
320
- # Make a new DX heating coil sized at 90% of the capacity
321
- # of the cooling coil.
322
- htg_coil = OpenStudio::Model::CoilHeatingDXSingleSpeed.new(model)
323
- mid_htg_cap_w = mid_clg_cap_w * 0.9
324
- htg_coil.setRatedTotalHeatingCapacity(mid_htg_cap_w)
325
-
326
- # If it is a PTHP Coil, add to PTHP
327
- # If not, add to unitary HP
328
- if props['subcategory'] == 'PTHP'
329
- if props['heating_type'] == 'Electric Resistance or None'
330
- backup_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model)
331
- backup_htg_coil.setName('PTHP Electric Backup Htg Coil')
332
- else
333
- backup_htg_coil = OpenStudio::Model::CoilHeatingGas.new(model)
334
- backup_htg_coil.setName('PTHP Electric Backup Htg Coil')
335
- end
336
- fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
337
- fan.setName("PTHP Supply Fan")
338
- pthp = OpenStudio::Model::ZoneHVACPackagedTerminalHeatPump.new(model,
339
- model.alwaysOnDiscreteSchedule,
340
- fan,
341
- htg_coil,
342
- clg_coil,
343
- backup_htg_coil)
344
- else
345
- if props['heating_type'] == 'Electric Resistance or None'
346
- backup_htg_coil = OpenStudio::Model::CoilHeatingElectric.new(model)
347
- backup_htg_coil.setName('Unitary Heat Pump Electric Backup Htg Coil')
348
- else
349
- backup_htg_coil = OpenStudio::Model::CoilHeatingGas.new(model)
350
- backup_htg_coil.setName('Unitary Heat Pump Electric Backup Htg Coil')
351
389
  end
352
- fan = OpenStudio::Model::FanOnOff.new(model, model.alwaysOnDiscreteSchedule)
353
- fan.setName("Unitary Heat Pump Supply Fan")
354
- unitary_system = OpenStudio::Model::AirLoopHVACUnitaryHeatPumpAirToAir.new(model,
355
- model.alwaysOnDiscreteSchedule,
356
- fan,
357
- htg_coil,
358
- clg_coil,
359
- backup_htg_coil)
360
- unitary_system.setName("Unitary Heat Pump")
361
- unitary_system.setMaximumOutdoorDryBulbTemperatureforSupplementalHeaterOperation(OpenStudio.convert(40, 'F', 'C').get)
362
390
  end
363
391
 
364
- # Apply the standard
365
- std_applier.coil_cooling_dx_single_speed_apply_efficiency_and_curves(clg_coil, {})
366
- std_applier.coil_heating_dx_single_speed_apply_efficiency_and_curves(htg_coil, {})
367
-
368
- # Reset the capacity
369
- clg_coil.autosizeRatedTotalCoolingCapacity
370
- htg_coil.autosizeRatedTotalHeatingCapacity
371
-
372
- # Modify the name of the boiler to reflect the capacity range
373
- min_clg_cap_kbtu_per_hr = OpenStudio.convert(min_clg_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
374
- max_clg_cap_kbtu_per_hr = OpenStudio.convert(max_clg_cap_btu_per_hr, 'Btu/hr', 'kBtu/hr').get.round
375
-
376
- # Modify the name of the dx_coil to reflect the capacity range
377
- old_name = clg_coil.name.get.to_s
378
- m = old_name.match(/(\d+)kBtu\/hr/)
379
- if m
380
- # Put the fuel type into the name
381
- old_type = 'Coil Cooling DX Single Speed 1'
382
- new_type = "#{props['cooling_type']} #{props['heating_type']} #{props['subcategory']} DX"
383
- new_name = old_name.gsub(old_type, new_type)
384
- # Swap out the capacity number for a range
385
- old_cap = m[1]
386
- if max_clg_cap_kbtu_per_hr == 10_000 # Value representing infinity
387
- new_cap = "> #{min_clg_cap_kbtu_per_hr}"
388
- else
389
- new_cap = "#{min_clg_cap_kbtu_per_hr}-#{max_clg_cap_kbtu_per_hr}"
390
- end
391
- new_name = new_name.gsub(old_cap, new_cap)
392
- clg_coil.setName(new_name)
393
- puts "#{props['template']}: #{clg_coil.name.get.to_s}"
394
-
395
- # Rename PTHP or unitary same as the cooling coil
396
- if pthp
397
- pthp.setName("PTHP #{new_name}")
398
- else
399
- unitary_system.setName("Unitary Heat Pump #{new_name}")
392
+ # Construction Sets, Constructions, and Materials
393
+ # TODO fix code to remove duplicate constructions and materials
394
+ if include_construction_sets
395
+ puts "* Construction Sets *"
396
+ std.standards_data['construction_sets'].each do |props|
397
+ next unless props['template'] == template_name
398
+ # Add a construction set for each valid climate zone
399
+ templates_to_climate_zones[props['template']].each do |climate_zone|
400
+ construction_set = std_applier.model_add_construction_set(model,
401
+ climate_zone,
402
+ props['building_type'],
403
+ props['space_type'],
404
+ props['is_residential'])
405
+ end
400
406
  end
407
+ end
401
408
 
402
- # Rename the heating coil
403
- old_type = 'Coil Heating DX Single Speed 1'
404
- new_type = "#{props['cooling_type']} #{props['heating_type']} #{props['subcategory']} DX"
405
- new_name = old_name.gsub(old_type, new_type)
406
- # Swap out the capacity number for a blank
407
- old_cap = m[1]
408
- new_name = new_name.gsub(old_cap, '')
409
- htg_coil.setName(new_name)
410
-
409
+ # Delete all the unused curves
410
+ puts '* Cleaning up the unused curves *'
411
+ model.getCurves.sort.each do |curve|
412
+ if curve.directUseCount == 0
413
+ puts " #{curve.name} is unused; successfully removed? #{model.removeObject(curve.handle)}."
414
+ # curve.remove # For some reason curve.remove doesn't work properly
415
+ end
411
416
  end
412
417
 
418
+ # Save the library
419
+ osm_lib_dir = "#{__dir__}/../../pkg/libraries"
420
+ Dir.mkdir(osm_lib_dir) unless Dir.exists?(osm_lib_dir)
421
+ library_path = "#{osm_lib_dir}/#{template_name.gsub(/\W/,'_')}.osm"
422
+ puts "* Saving library #{library_path}"
423
+ model.save(OpenStudio::Path.new(library_path), true)
424
+
425
+ # Save the log messages for debugging library creation
426
+ log_path = "#{osm_lib_dir}/#{template_name.gsub(/\W/,'_')}.log"
427
+ puts "* Saving log #{log_path}"
428
+ log_messages_to_file(log_path, debug=false)
429
+
430
+ # Show the timing
431
+ template_end_time = Time.now
432
+ template_time_min = ((template_end_time - template_start_time)/60.0).round(1)
433
+ puts "* Finished #{template_name} at: #{template_end_time}, time elapsed = #{template_time_min} min."
434
+
435
+ rescue Exception => exc
436
+ puts "ERROR creating '#{template_name}', skipping to next template."
437
+ puts "#{exc}"
438
+ puts "Backtrace:\n\t#{e.caller.join("\n\t")}"
439
+ puts "Backtrace:\n\t#{e.backtrace.join("\n\t")}"
440
+
441
+ # Save the log messages for debugging library creation even on failure
442
+ log_path = "#{osm_lib_dir}/#{template_name.gsub(/\W/,'_')}.log"
443
+ puts "* Saving log #{log_path}"
444
+ log_messages_to_file(log_path, debug=false)
413
445
  end
414
- end
415
446
 
416
- # Delete all the unused curves
417
- puts 'Cleaning up the unused curves'
418
- template_to_lib_models.each do |template, data|
419
- puts ''
420
- puts "***#{template}***"
421
- data['model'].getCurves.sort.each do |curve|
422
- if curve.directUseCount == 0
423
- puts " #{curve.name} is unused; successfully removed? #{data['model'].removeObject(curve.handle)}."
424
- # curve.remove # For some reason curve.remove doesn't work properly
425
- end
426
- end
427
447
  end
428
448
 
429
- # Save the libraries
430
- osm_lib_dir = "#{__dir__}/../../pkg/libraries"
431
- Dir.mkdir(osm_lib_dir) unless Dir.exists?(osm_lib_dir)
432
- template_to_lib_models.each do |template, data|
433
- library_path = "#{osm_lib_dir}/#{template.gsub(/\W/,'_')}.osm"
434
- puts "Saving library #{library_path}"
435
- data['model'].save(OpenStudio::Path.new(library_path), true)
436
- end
449
+ # Show the timing
450
+ end_time = Time.now
451
+ total_time_min = ((end_time - start_time)/60.0).round(1)
452
+ puts "*** Finished all templates at: #{end_time}, time elapsed = #{total_time_min} min."
437
453
 
438
454
  end
@@ -1,7 +1,6 @@
1
1
  # This script reads OpenStudio_standards.xlsx
2
2
  # and creates a JSON file containing all the information
3
3
 
4
- require 'rubygems'
5
4
  require 'json'
6
5
  require 'rubyXL'
7
6
 
@@ -22,7 +22,6 @@ require "#{File.dirname(__FILE__)}/btap"
22
22
  require 'fileutils'
23
23
  require 'csv'
24
24
  require 'securerandom'
25
- #require 'rubygems'
26
25
 
27
26
 
28
27
  module BTAP
@@ -71,8 +71,8 @@ module Hospital
71
71
  elec_equip_def1.setDesignLevel(915)
72
72
  elec_equip_def2.setDesignLevel(855)
73
73
  else
74
- elec_equip_def1.setDesignLevel(99_999.88)
75
- elec_equip_def2.setDesignLevel(99_999.99)
74
+ elec_equip_def1.setDesignLevel(915)
75
+ elec_equip_def2.setDesignLevel(855)
76
76
  end
77
77
  # Create the electric equipment instance and hook it up to the space type
78
78
  elec_equip1 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def1)
@@ -106,8 +106,8 @@ module LargeHotel
106
106
  elec_equip_def1.setDesignLevel(457.7)
107
107
  elec_equip_def2.setDesignLevel(285)
108
108
  else
109
- elec_equip_def1.setDesignLevel(99_999.88)
110
- elec_equip_def2.setDesignLevel(99_999.99)
109
+ elec_equip_def1.setDesignLevel(457.7)
110
+ elec_equip_def2.setDesignLevel(285)
111
111
  end
112
112
  # Create the electric equipment instance and hook it up to the space type
113
113
  elec_equip1 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def1)
@@ -33,8 +33,8 @@ module PrimarySchool
33
33
  elec_equip_def1.setDesignLevel(915)
34
34
  elec_equip_def2.setDesignLevel(570)
35
35
  else
36
- elec_equip_def1.setDesignLevel(99_999.88)
37
- elec_equip_def2.setDesignLevel(99_999.99)
36
+ elec_equip_def1.setDesignLevel(1032)
37
+ elec_equip_def2.setDesignLevel(852)
38
38
  end
39
39
  # Create the electric equipment instance and hook it up to the space type
40
40
  elec_equip1 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def1)
@@ -49,8 +49,8 @@ module SecondarySchool
49
49
  elec_equip_def1.setDesignLevel(915)
50
50
  elec_equip_def2.setDesignLevel(570)
51
51
  else
52
- elec_equip_def1.setDesignLevel(99_999.88)
53
- elec_equip_def2.setDesignLevel(99_999.99)
52
+ elec_equip_def1.setDesignLevel(1032)
53
+ elec_equip_def2.setDesignLevel(852)
54
54
  end
55
55
  # Create the electric equipment instance and hook it up to the space type
56
56
  elec_equip1 = OpenStudio::Model::ElectricEquipment.new(elec_equip_def1)
@@ -78,4 +78,17 @@ module References
78
78
  # @see http://deeresources.com/index.php/deer-versions
79
79
  class DEERMASControl; end
80
80
 
81
+ # OEESC 2014
82
+ # The Oregon Energy Efficiency Specialty Code is the building energy code for the
83
+ # state of Oregon. It is very similar to ASHRAE 90.1-2013, but has been tailored
84
+ # to meet the needs of Oregon.
85
+ # @see http://www.oregon.gov/bcd/codes-stand/Pages/energy-efficiency.aspx
86
+ class OEESC2014; end
87
+
88
+ # ICC IECC 2015
89
+ # The International Code Council's International Energy Conservation Code is widely
90
+ # used across the United States.
91
+ # @see https://codes.iccsafe.org/public/document/toc/545/
92
+ class ICCIECC2015; end
93
+
81
94
  end
@@ -265,7 +265,7 @@ class Standard
265
265
  # Only applies to fenestration constructions.
266
266
  # @return [Double] the SHGC as a decimal.
267
267
  def construction_calculated_solar_heat_gain_coefficient(construction)
268
- construction_name = name.get.to_s
268
+ construction_name = construction.name.get.to_s
269
269
 
270
270
  shgc = nil
271
271
 
@@ -286,7 +286,7 @@ class Standard
286
286
  if row_id.is_initialized
287
287
  row_id = row_id.get
288
288
  else
289
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "SHGC row ID not found for construction: #{construction_name}.")
289
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Construction', "SHGC row ID not found for construction: #{construction_name}.")
290
290
  row_id = 9999
291
291
  end
292
292
 
@@ -315,7 +315,7 @@ class Standard
315
315
  # Only applies to fenestration constructions.
316
316
  # @return [Double] the visible transmittance as a decimal.
317
317
  def construction_calculated_visible_transmittance(construction)
318
- construction_name = name.get.to_s
318
+ construction_name = construction.name.get.to_s
319
319
 
320
320
  vt = nil
321
321
 
@@ -365,7 +365,7 @@ class Standard
365
365
  # Only applies to fenestration constructions.
366
366
  # @return [Double] the U-Factor in W/m^2*K.
367
367
  def construction_calculated_u_factor(construction)
368
- construction_name = name.get.to_s
368
+ construction_name = construction.name.get.to_s
369
369
 
370
370
  u_factor_w_per_m2_k = nil
371
371
 
@@ -386,7 +386,7 @@ class Standard
386
386
  if row_id.is_initialized
387
387
  row_id = row_id.get
388
388
  else
389
- OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Model', "U-Factor row ID not found for construction: #{construction_name}.")
389
+ OpenStudio.logFree(OpenStudio::Warn, 'openstudio.model.Construction', "U-Factor row ID not found for construction: #{construction_name}.")
390
390
  row_id = 9999
391
391
  end
392
392
 
@@ -405,7 +405,7 @@ class Standard
405
405
  end
406
406
 
407
407
  else
408
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Space', 'Model has no sql file containing results, cannot lookup data.')
408
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Construction', 'Model has no sql file containing results, cannot lookup data.')
409
409
  end
410
410
 
411
411
  return u_factor_w_per_m2_k
@@ -4011,7 +4011,7 @@ class Standard
4011
4011
 
4012
4012
  parts = [template]
4013
4013
 
4014
- unless building_type.empty?
4014
+ unless building_type.nil?
4015
4015
  parts << building_type
4016
4016
  end
4017
4017
 
@@ -278,13 +278,24 @@ module Pump
278
278
  end
279
279
 
280
280
  rated_m3_per_s = 0
281
- if pump.autosizedRatedFlowRate.is_initialized
282
- rated_m3_per_s = pump.autosizedRatedFlowRate.get
283
- elsif pump.ratedFlowRate.is_initialized
284
- rated_m3_per_s = pump.ratedFlowRate.get
285
- else
286
- OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Pump', "For #{pump.name}, could not find rated pump Flow Rate, cannot determine w per gpm correctly.")
287
- return 0.0
281
+ if pump.to_PumpVariableSpeed.is_initialized || pump.to_PumpConstantSpeed.is_initialized
282
+ if pump.ratedFlowRate.is_initialized
283
+ rated_m3_per_s = pump.ratedFlowRate.get
284
+ elsif pump.autosizedRatedFlowRate.is_initialized
285
+ rated_m3_per_s = pump.autosizedRatedFlowRate.get
286
+ else
287
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Pump', "For #{pump.name}, could not find rated pump Flow Rate, cannot determine w per gpm correctly.")
288
+ return 0.0
289
+ end
290
+ elsif pump.to_HeaderedPumpsVariableSpeed.is_initialized || pump.to_HeaderedPumpsConstantSpeed.is_initialized
291
+ if pump.totalRatedFlowRate.is_initialized
292
+ rated_m3_per_s = pump.totalRatedFlowRate.get
293
+ elsif pump.autosizedTotalRatedFlowRate.is_initialized
294
+ rated_m3_per_s = pump.autosizedTotalRatedFlowRate.get
295
+ else
296
+ OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.Pump', "For #{pump.name}, could not find rated pump Flow Rate, cannot determine w per gpm correctly.")
297
+ return 0.0
298
+ end
288
299
  end
289
300
 
290
301
  rated_w_per_m3s = rated_power_w / rated_m3_per_s
@@ -79,7 +79,7 @@ class Standard
79
79
 
80
80
  previous_time_decimal = 0
81
81
  times.each_with_index do |time, i|
82
- time_decimal = (time.days * 24) + time.hours + (time.minutes / 60) + (time.seconds / 3600)
82
+ time_decimal = (time.days * 24.0) + time.hours + (time.minutes / 60.0) + (time.seconds / 3600.0)
83
83
  duration_of_value = time_decimal - previous_time_decimal
84
84
  # OpenStudio::logFree(OpenStudio::Debug, "openstudio.standards.ScheduleRuleset", " Value of #{values[i]} for #{duration_of_value} hours")
85
85
  daily_flh += values[i] * duration_of_value
@@ -219,7 +219,7 @@ class Standard
219
219
 
220
220
  previous_time_decimal = 0
221
221
  times.each_with_index do |time, i|
222
- time_decimal = (time.days * 24) + time.hours + (time.minutes / 60) + (time.seconds / 3600)
222
+ time_decimal = (time.days * 24.0) + time.hours + (time.minutes / 60.0) + (time.seconds / 3600.0)
223
223
  duration_of_value = time_decimal - previous_time_decimal
224
224
  # OpenStudio::logFree(OpenStudio::Debug, "openstudio.standards.ScheduleRuleset", " Value of #{values[i]} for #{duration_of_value} hours")
225
225
  daily_hrs += values[i] * duration_of_value
@@ -396,7 +396,7 @@ class Standard
396
396
  # Electricity, NaturalGas, PropaneGas, FuelOil#1, FuelOil#2,
397
397
  # Coal, Diesel, Gasoline, DistrictHeating,
398
398
  # and SolarEnergy.
399
- htg_fuels = heating_fuels
399
+ htg_fuels = thermal_zone.heating_fuels
400
400
 
401
401
  if htg_fuels.include?('NaturalGas') ||
402
402
  htg_fuels.include?('PropaneGas') ||
@@ -498,7 +498,7 @@ class Standard
498
498
  # Electricity, NaturalGas, PropaneGas, FuelOil#1, FuelOil#2,
499
499
  # Coal, Diesel, Gasoline, DistrictHeating,
500
500
  # and SolarEnergy.
501
- htg_fuels = heating_fuels
501
+ htg_fuels = thermal_zone.heating_fuels
502
502
 
503
503
  # Includes fossil
504
504
  fossil = false
@@ -576,7 +576,7 @@ class Standard
576
576
  has_ptac = false
577
577
  has_pthp = false
578
578
  has_unitheater = false
579
- equipment.each do |equip|
579
+ thermal_zone.equipment.each do |equip|
580
580
  # Skip HVAC components
581
581
  next unless equip.to_HVACComponent.is_initialized
582
582
  equip = equip.to_HVACComponent.get
@@ -601,8 +601,8 @@ class Standard
601
601
  end
602
602
 
603
603
  # Get the zone heating and cooling fuels
604
- htg_fuels = heating_fuels
605
- clg_fuels = cooling_fuels
604
+ htg_fuels = thermal_zone.heating_fuels
605
+ clg_fuels = thermal_zone.cooling_fuels
606
606
  is_fossil = thermal_zone_fossil_hybrid_or_purchased_heat?(thermal_zone)
607
607
 
608
608
  # Infer the HVAC type
@@ -615,7 +615,7 @@ class Standard
615
615
  # Air Loop
616
616
  if has_air_loop
617
617
  # Gas_Furnace (as air loop)
618
- sys_type = if cooling_fuels.size.zero?
618
+ sys_type = if clg_fuels.size.zero?
619
619
  'Gas_Furnace'
620
620
  # PSZ_AC
621
621
  else
@@ -637,7 +637,7 @@ class Standard
637
637
  # Air Loop
638
638
  if has_air_loop
639
639
  # Electric_Furnace (as air loop)
640
- sys_type = if cooling_fuels.size.zero?
640
+ sys_type = if clg_fuels.size.zero?
641
641
  'Electric_Furnace'
642
642
  # PSZ_HP
643
643
  else
@@ -0,0 +1,9 @@
1
+ # This abstract class holds methods that many versions of ICC IECC share.
2
+ # If a method in this class is redefined by a subclass,
3
+ # the implementation in the subclass is used.
4
+ # @abstract
5
+ class ICCIECC < Standard
6
+ def initialize
7
+ super()
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # This class will hold methods that apply ICC IECC 2015
2
+ # to a given model.
3
+ # @todo ICC IECC 2015 is incomplete and will default to the logic
4
+ # in the default Standard class methods
5
+ # @ref [References::ICCIECC2015]
6
+ class ICCIECC2015 < ICCIECC
7
+ @@template = 'ICC IECC 2015' # rubocop:disable Style/ClassVars
8
+ register_standard @@template
9
+ attr_reader :template
10
+
11
+ def initialize
12
+ super()
13
+ @template = @@template
14
+ load_standards_database
15
+ end
16
+ end
@@ -1,6 +1,5 @@
1
1
  # This class holds methods that apply NECB2011 rules.
2
2
  # @ref [References::NECB2011]
3
- require 'rubyXL'
4
3
  class NECB2011 < Standard
5
4
  @template = self.new.class.name # rubocop:disable Style/ClassVars
6
5
  register_standard(@template)
@@ -1,6 +1,5 @@
1
1
  # This class holds methods that apply NECB2011 rules.
2
2
  # @ref [References::NECB2011]
3
- require 'rubyXL'
4
3
  class NECB2015 < NECB2011
5
4
  @template = self.new.class.name # rubocop:disable Style/ClassVars
6
5
  register_standard(@template)
@@ -0,0 +1,9 @@
1
+ # This abstract class holds methods that many versions of OEESC share.
2
+ # If a method in this class is redefined by a subclass,
3
+ # the implementation in the subclass is used.
4
+ # @abstract
5
+ class OEESC < Standard
6
+ def initialize
7
+ super()
8
+ end
9
+ end
@@ -0,0 +1,16 @@
1
+ # This class will hold methods that apply OEESC 2014
2
+ # to a given model.
3
+ # @todo OEESC 2014 is incomplete and will default to the logic
4
+ # in the default Standard class methods
5
+ # @ref [References::OEESC2014]
6
+ class OEESC2014 < OEESC
7
+ @@template = 'OEESC 2014' # rubocop:disable Style/ClassVars
8
+ register_standard @@template
9
+ attr_reader :template
10
+
11
+ def initialize
12
+ super()
13
+ @template = @@template
14
+ load_standards_database
15
+ end
16
+ end
@@ -13,5 +13,5 @@ module OpenstudioStandards
13
13
  end
14
14
  return 'git-not-found-on-this-system'
15
15
  end
16
- VERSION = '0.2.0.rc1'.freeze
16
+ VERSION = '0.2.0.rc2'.freeze
17
17
  end
@@ -85,6 +85,12 @@ module OpenstudioStandards
85
85
  require_relative "#{stds}/deer/deer_2015/deer_2015"
86
86
  require_relative "#{stds}/deer/deer_2017/deer_2017"
87
87
 
88
+ require_relative "#{stds}/oeesc/oeesc"
89
+ require_relative "#{stds}/oeesc/oeesc_2014/oeesc_2014"
90
+
91
+ require_relative "#{stds}/icc_iecc/icc_iecc"
92
+ require_relative "#{stds}/icc_iecc/icc_iecc_2015/icc_iecc_2015"
93
+
88
94
  # Files with modules
89
95
  require_relative "#{stds}/Standards.Fan"
90
96
  require_relative "#{stds}/Standards.CoilDX"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: openstudio-standards
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.rc1
4
+ version: 0.2.0.rc2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew Parker
@@ -21,7 +21,7 @@ authors:
21
21
  autorequire:
22
22
  bindir: bin
23
23
  cert_chain: []
24
- date: 2018-02-17 00:00:00.000000000 Z
24
+ date: 2018-03-16 00:00:00.000000000 Z
25
25
  dependencies:
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: minitest-reporters
@@ -141,14 +141,14 @@ dependencies:
141
141
  requirements:
142
142
  - - "~>"
143
143
  - !ruby/object:Gem::Version
144
- version: '0.50'
144
+ version: '0.53'
145
145
  type: :development
146
146
  prerelease: false
147
147
  version_requirements: !ruby/object:Gem::Requirement
148
148
  requirements:
149
149
  - - "~>"
150
150
  - !ruby/object:Gem::Version
151
- version: '0.50'
151
+ version: '0.53'
152
152
  - !ruby/object:Gem::Dependency
153
153
  name: rubocop-checkstyle_formatter
154
154
  requirement: !ruby/object:Gem::Requirement
@@ -1560,6 +1560,8 @@ files:
1560
1560
  - lib/openstudio-standards/standards/deer/deer_2015/deer_2015.rb
1561
1561
  - lib/openstudio-standards/standards/deer/deer_2017/deer_2017.rb
1562
1562
  - lib/openstudio-standards/standards/deer/deer_pre_1975/deer_pre_1975.rb
1563
+ - lib/openstudio-standards/standards/icc_iecc/icc_iecc.rb
1564
+ - lib/openstudio-standards/standards/icc_iecc/icc_iecc_2015/icc_iecc_2015.rb
1563
1565
  - lib/openstudio-standards/standards/necb/necb_2011/beps_compliance_path.rb
1564
1566
  - lib/openstudio-standards/standards/necb/necb_2011/building_envelope.rb
1565
1567
  - lib/openstudio-standards/standards/necb/necb_2011/data/boilers.json
@@ -1592,6 +1594,8 @@ files:
1592
1594
  - lib/openstudio-standards/standards/necb/necb_2011/necb_2011.rb
1593
1595
  - lib/openstudio-standards/standards/necb/necb_2011/service_water_heating.rb
1594
1596
  - lib/openstudio-standards/standards/necb/necb_2015/necb_2015.rb
1597
+ - lib/openstudio-standards/standards/oeesc/oeesc.rb
1598
+ - lib/openstudio-standards/standards/oeesc/oeesc_2014/oeesc_2014.rb
1595
1599
  - lib/openstudio-standards/standards/standard.rb
1596
1600
  - lib/openstudio-standards/utilities/convert_costing_constructions.rb
1597
1601
  - lib/openstudio-standards/utilities/define_thermal_zone_and_mulitpliers.rb