honeybee-openstudio 2.16.3 → 2.17.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -36,7 +36,7 @@ module Honeybee
36
36
  attr_reader :errors, :warnings
37
37
 
38
38
  @@all_air_types = ['VAV', 'PVAV', 'PSZ', 'PTAC', 'ForcedAirFurnace']
39
- @@doas_types = ['FCUwithDOAS', 'WSHPwithDOAS', 'VRFwithDOAS']
39
+ @@doas_types = ['FCUwithDOASAbridged', 'WSHPwithDOASAbridged', 'VRFwithDOASAbridged']
40
40
  @@heat_cool_types = ['FCU', 'WSHP', 'VRF', 'Baseboard', 'EvaporativeCooler',
41
41
  'Residential', 'WindowAC', 'GasUnitHeater']
42
42
  @@types = @@all_air_types + @@doas_types + @@heat_cool_types
@@ -45,8 +45,6 @@ module Honeybee
45
45
  def to_openstudio(openstudio_model)
46
46
  os_construction = OpenStudio::Model::ConstructionAirBoundary.new(openstudio_model)
47
47
  os_construction.setName(@hash[:identifier])
48
- os_construction.setSolarAndDaylightingMethod('GroupedZones')
49
- os_construction.setRadiantExchangeMethod('GroupedZones')
50
48
  os_construction.setAirExchangeMethod('None')
51
49
 
52
50
  os_construction
@@ -50,8 +50,12 @@ module Honeybee
50
50
  # create material vector
51
51
  os_materials = OpenStudio::Model::MaterialVector.new
52
52
  # loop through each layer and add to material vector
53
- @hash[:layers].each do |layer|
54
- material_identifier = layer
53
+ if @hash.key?(:layers)
54
+ mat_key = :layers
55
+ else
56
+ mat_key = :materials
57
+ end
58
+ @hash[mat_key].each do |material_identifier|
55
59
  material = openstudio_model.getMaterialByName(material_identifier)
56
60
  unless material.empty?
57
61
  os_material = material.get
@@ -50,8 +50,12 @@ module Honeybee
50
50
  # create material vector
51
51
  os_materials = OpenStudio::Model::MaterialVector.new
52
52
  # loop through each layer and add to material vector
53
- @hash[:layers].each do |layer|
54
- material_identifier = layer
53
+ if @hash.key?(:layers)
54
+ mat_key = :layers
55
+ else
56
+ mat_key = :materials
57
+ end
58
+ @hash[mat_key].each do |material_identifier|
55
59
  material = openstudio_model.getMaterialByName(material_identifier)
56
60
  unless material.empty?
57
61
  os_material = material.get
@@ -62,8 +62,12 @@ module Honeybee
62
62
 
63
63
  # create the layers of the unshaded construction into which we will insert the shade
64
64
  os_materials = []
65
- @hash[:window_construction][:layers].each do |layer|
66
- material_identifier = layer
65
+ if @hash.key?(:layers)
66
+ mat_key = :layers
67
+ else
68
+ mat_key = :materials
69
+ end
70
+ @hash[:window_construction][mat_key].each do |material_identifier|
67
71
  material = openstudio_model.getMaterialByName(material_identifier)
68
72
  unless material.empty?
69
73
  os_material = material.get
@@ -91,6 +91,7 @@ module Honeybee
91
91
  os_air_loop = os_air_loop_opt.get
92
92
  loop_name = os_air_loop.name
93
93
  unless loop_name.empty?
94
+ # set the name of the air loop to align with the HVAC name
94
95
  if @hash[:display_name]
95
96
  clean_name = @hash[:display_name].to_s.gsub(/[^.A-Za-z0-9_-] /, " ")
96
97
  os_air_loop.setName(clean_name + ' - ' + loop_name.get)
@@ -101,17 +102,17 @@ module Honeybee
101
102
  end
102
103
 
103
104
  # assign the economizer type if there's an air loop and the economizer is specified
104
- if @hash[:economizer_type] && @hash[:economizer_type] != 'Inferred' && os_air_loop
105
+ if @hash[:economizer_type] && os_air_loop
105
106
  oasys = os_air_loop.airLoopHVACOutdoorAirSystem
106
107
  unless oasys.empty?
107
- os_oasys = oasys.get
108
- oactrl = os_oasys.getControllerOutdoorAir
109
- oactrl.setEconomizerControlType(@hash[:economizer_type])
108
+ os_oasys = oasys.get
109
+ oactrl = os_oasys.getControllerOutdoorAir
110
+ oactrl.setEconomizerControlType(@hash[:economizer_type])
110
111
  end
111
112
  end
112
113
 
113
114
  # set the sensible heat recovery if there's an air loop and the heat recovery is specified
114
- if @hash[:sensible_heat_recovery] && @hash[:sensible_heat_recovery] != {:type => 'Autosize'} && os_air_loop
115
+ if @hash[:sensible_heat_recovery] && @hash[:sensible_heat_recovery] != 0 && os_air_loop
115
116
  erv = get_existing_erv(os_air_loop)
116
117
  unless erv
117
118
  erv = create_erv(openstudio_model, os_air_loop)
@@ -124,7 +125,7 @@ module Honeybee
124
125
  end
125
126
 
126
127
  # set the latent heat recovery if there's an air loop and the heat recovery is specified
127
- if @hash[:latent_heat_recovery] && @hash[:latent_heat_recovery] != {:type => 'Autosize'} && os_air_loop
128
+ if @hash[:latent_heat_recovery] && @hash[:latent_heat_recovery] != 0 && os_air_loop
128
129
  erv = get_existing_erv(os_air_loop)
129
130
  unless erv
130
131
  erv = create_erv(openstudio_model, os_air_loop)
@@ -136,6 +137,60 @@ module Honeybee
136
137
  erv.setLatentEffectivenessat75HeatingAirFlow(@hash[:latent_heat_recovery])
137
138
  end
138
139
 
140
+ # assign demand controlled ventilation if there's an air loop
141
+ if @hash[:demand_controlled_ventilation] && os_air_loop
142
+ oasys = os_air_loop.airLoopHVACOutdoorAirSystem
143
+ unless oasys.empty?
144
+ os_oasys = oasys.get
145
+ oactrl = os_oasys.getControllerOutdoorAir
146
+ vent_ctrl = oactrl.controllerMechanicalVentilation
147
+ vent_ctrl.setDemandControlledVentilationNoFail(true)
148
+ oactrl.resetMinimumFractionofOutdoorAirSchedule
149
+ end
150
+ end
151
+
152
+ # assign the DOAS availability schedule if there's an air loop and it is specified
153
+ if @hash[:doas_availability_schedule] && os_air_loop
154
+ schedule = openstudio_model.getScheduleByName(@hash[:doas_availability_schedule])
155
+ unless schedule.empty?
156
+ avail_sch = schedule.get
157
+ os_air_loop.setAvailabilitySchedule(avail_sch)
158
+ end
159
+ end
160
+
161
+ # set the outdoor air controller to respect room-level ventilation schedules if they exist
162
+ if os_air_loop
163
+ oasys = os_air_loop.airLoopHVACOutdoorAirSystem
164
+ unless oasys.empty?
165
+ os_oasys = oasys.get
166
+ oactrl = os_oasys.getControllerOutdoorAir
167
+ oa_sch, oa_sch_name = nil, nil
168
+ zones.each do |zone|
169
+ oa_spec = zone.spaces[0].designSpecificationOutdoorAir
170
+ unless oa_spec.empty?
171
+ oa_spec = oa_spec.get
172
+ space_oa_sch = oa_spec.outdoorAirFlowRateFractionSchedule
173
+ unless space_oa_sch.empty?
174
+ space_oa_sch = space_oa_sch.get
175
+ space_oa_sch_name = space_oa_sch.name
176
+ unless space_oa_sch_name.empty?
177
+ space_oa_sch_name = space_oa_sch_name.get
178
+ if oa_sch_name.nil? || space_oa_sch_name == oa_sch_name
179
+ oa_sch, oa_sch_name = space_oa_sch, space_oa_sch_name
180
+ else
181
+ oa_sch = nil
182
+ end
183
+ end
184
+ end
185
+ end
186
+ end
187
+ if oa_sch
188
+ oactrl.resetMinimumFractionofOutdoorAirSchedule
189
+ oactrl.setMinimumOutdoorAirSchedule(oa_sch)
190
+ end
191
+ end
192
+ end
193
+
139
194
  # if the systems are PTAC and there is ventilation, ensure the system includes it
140
195
  if equipment_type.include?('PTAC') || equipment_type.include?('PTHP')
141
196
  always_on = openstudio_model.getScheduleByName('Always On').get
@@ -172,6 +227,20 @@ module Honeybee
172
227
  end
173
228
  end
174
229
 
230
+ # assign an electric humidifier if there's an air loop and the zones have a humidistat
231
+ if os_air_loop
232
+ humidistat_exists = false
233
+ zones.each do |zone|
234
+ h_stat = zone.zoneControlHumidistat
235
+ unless h_stat.empty?
236
+ humidistat_exists = true
237
+ end
238
+ end
239
+ if humidistat_exists
240
+ humidifier = create_humidifier(openstudio_model, os_air_loop)
241
+ end
242
+ end
243
+
175
244
  # set all plants to non-coincident sizing to avoid simualtion control issues on design days
176
245
  openstudio_model.getPlantLoops.each do |loop|
177
246
  sizing = loop.sizingPlant
@@ -217,5 +286,20 @@ module Honeybee
217
286
  heat_ex
218
287
  end
219
288
 
289
+ def create_humidifier(model, os_air_loop)
290
+ # create an electric humidifier
291
+ humidifier = OpenStudio::Model::HumidifierSteamElectric.new(model)
292
+ humidifier.setName(@hash[:identifier] + '_Humidifier Unit')
293
+ humid_controller = OpenStudio::Model::SetpointManagerMultiZoneHumidityMinimum.new(model)
294
+ humid_controller.setName(@hash[:identifier] + '_Humidifier Controller')
295
+
296
+ # add the humidifier to the air loop
297
+ supply_node = os_air_loop.supplyOutletNode
298
+ humidifier.addToNode(supply_node)
299
+ humid_controller.addToNode(supply_node)
300
+
301
+ humidifier
302
+ end
303
+
220
304
  end #TemplateHVAC
221
305
  end #Honeybee
@@ -203,7 +203,7 @@ module Honeybee
203
203
  os_schedule_file = OpenStudio::Model::ScheduleFile.new(os_external_file, column, rowsToSkip)
204
204
  os_schedule_file.setName(@hash[:identifier])
205
205
  os_schedule_file.setInterpolatetoTimestep(interpolate)
206
- os_schedule_file.setMinutesperItem(interval_length.to_s)
206
+ os_schedule_file.setMinutesperItem(interval_length)
207
207
 
208
208
  # assign the schedule type limit
209
209
  if @hash[:schedule_type_limit]
metadata CHANGED
@@ -1,18 +1,102 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybee-openstudio
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.16.3
4
+ version: 2.17.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanushree Charan
8
8
  - Dan Macumber
9
9
  - Chris Mackey
10
10
  - Mostapha Sadeghipour Roudsari
11
- autorequire:
11
+ autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2021-04-29 00:00:00.000000000 Z
14
+ date: 2021-05-18 00:00:00.000000000 Z
15
15
  dependencies:
16
+ - !ruby/object:Gem::Dependency
17
+ name: bundler
18
+ requirement: !ruby/object:Gem::Requirement
19
+ requirements:
20
+ - - "~>"
21
+ - !ruby/object:Gem::Version
22
+ version: '2.1'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - "~>"
28
+ - !ruby/object:Gem::Version
29
+ version: '2.1'
30
+ - !ruby/object:Gem::Dependency
31
+ name: public_suffix
32
+ requirement: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - "~>"
35
+ - !ruby/object:Gem::Version
36
+ version: 3.1.1
37
+ type: :development
38
+ prerelease: false
39
+ version_requirements: !ruby/object:Gem::Requirement
40
+ requirements:
41
+ - - "~>"
42
+ - !ruby/object:Gem::Version
43
+ version: 3.1.1
44
+ - !ruby/object:Gem::Dependency
45
+ name: json-schema
46
+ requirement: !ruby/object:Gem::Requirement
47
+ requirements:
48
+ - - "~>"
49
+ - !ruby/object:Gem::Version
50
+ version: 2.8.1
51
+ type: :development
52
+ prerelease: false
53
+ version_requirements: !ruby/object:Gem::Requirement
54
+ requirements:
55
+ - - "~>"
56
+ - !ruby/object:Gem::Version
57
+ version: 2.8.1
58
+ - !ruby/object:Gem::Dependency
59
+ name: rake
60
+ requirement: !ruby/object:Gem::Requirement
61
+ requirements:
62
+ - - "~>"
63
+ - !ruby/object:Gem::Version
64
+ version: '13.0'
65
+ type: :development
66
+ prerelease: false
67
+ version_requirements: !ruby/object:Gem::Requirement
68
+ requirements:
69
+ - - "~>"
70
+ - !ruby/object:Gem::Version
71
+ version: '13.0'
72
+ - !ruby/object:Gem::Dependency
73
+ name: rspec
74
+ requirement: !ruby/object:Gem::Requirement
75
+ requirements:
76
+ - - "~>"
77
+ - !ruby/object:Gem::Version
78
+ version: '3.9'
79
+ type: :development
80
+ prerelease: false
81
+ version_requirements: !ruby/object:Gem::Requirement
82
+ requirements:
83
+ - - "~>"
84
+ - !ruby/object:Gem::Version
85
+ version: '3.9'
86
+ - !ruby/object:Gem::Dependency
87
+ name: rubocop
88
+ requirement: !ruby/object:Gem::Requirement
89
+ requirements:
90
+ - - "~>"
91
+ - !ruby/object:Gem::Version
92
+ version: 0.54.0
93
+ type: :development
94
+ prerelease: false
95
+ version_requirements: !ruby/object:Gem::Requirement
96
+ requirements:
97
+ - - "~>"
98
+ - !ruby/object:Gem::Version
99
+ version: 0.54.0
16
100
  - !ruby/object:Gem::Dependency
17
101
  name: json_pure
18
102
  requirement: !ruby/object:Gem::Requirement
@@ -33,28 +117,28 @@ dependencies:
33
117
  requirements:
34
118
  - - '='
35
119
  - !ruby/object:Gem::Version
36
- version: 0.3.2
120
+ version: 0.4.2
37
121
  type: :runtime
38
122
  prerelease: false
39
123
  version_requirements: !ruby/object:Gem::Requirement
40
124
  requirements:
41
125
  - - '='
42
126
  - !ruby/object:Gem::Version
43
- version: 0.3.2
127
+ version: 0.4.2
44
128
  - !ruby/object:Gem::Dependency
45
129
  name: openstudio-standards
46
130
  requirement: !ruby/object:Gem::Requirement
47
131
  requirements:
48
132
  - - "~>"
49
133
  - !ruby/object:Gem::Version
50
- version: 0.2.12
134
+ version: 0.2.13
51
135
  type: :runtime
52
136
  prerelease: false
53
137
  version_requirements: !ruby/object:Gem::Requirement
54
138
  requirements:
55
139
  - - "~>"
56
140
  - !ruby/object:Gem::Version
57
- version: 0.2.12
141
+ version: 0.2.13
58
142
  description: Library and measures for translating between Honeybee JSON schema and
59
143
  OpenStudio Model schema (OSM).
60
144
  email:
@@ -230,15 +314,15 @@ files:
230
314
  homepage: https://github.com/ladybug-tools/honeybee-openstudio-gem
231
315
  licenses: []
232
316
  metadata: {}
233
- post_install_message:
317
+ post_install_message:
234
318
  rdoc_options: []
235
319
  require_paths:
236
320
  - lib
237
321
  required_ruby_version: !ruby/object:Gem::Requirement
238
322
  requirements:
239
- - - ">="
323
+ - - "~>"
240
324
  - !ruby/object:Gem::Version
241
- version: '0'
325
+ version: 2.7.0
242
326
  required_rubygems_version: !ruby/object:Gem::Requirement
243
327
  requirements:
244
328
  - - ">="
@@ -246,7 +330,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
246
330
  version: '0'
247
331
  requirements: []
248
332
  rubygems_version: 3.1.2
249
- signing_key:
333
+ signing_key:
250
334
  specification_version: 4
251
335
  summary: Gem for translating between Honeybee JSON and OpenStudio Model.
252
336
  test_files: []