honeybee-openstudio 2.16.3 → 2.17.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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: []