honeybee-openstudio 2.6.2 → 2.6.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 58a653751b8089a138bf8801ec4b364cc80ac8b32ea2a92e07baa138b3a800e5
4
- data.tar.gz: fbc8b5a03386731492f61feb8728e45a8658002f6a92ff785b2714d6f24ce9ea
3
+ metadata.gz: 0b0da04a58221bdf1cd64089755dadb753e9c45feb2966a983a7aa9574dea77a
4
+ data.tar.gz: ef763660f47e53e7336f0b48cbaf99b89c924dbee72bef048977485d483db49e
5
5
  SHA512:
6
- metadata.gz: 95f905265f9aa6c3765dc39cff0e0654b058f66d7e75070b80c52ffeb27c708e7859a9ced7290c6aa2dcbaa6af4df50afd4047a5c54e2fdf723a012e60c9b600
7
- data.tar.gz: 85621370e9d5a0e3a4f120cbde34fc1187791d2c8fb4283d3cfca9272894e1ae2fac73feb03eabd300db282b2e33193acff242625b95fb83e8afa06d155ced32
6
+ metadata.gz: 862f2c7fa88498e78141a6293797e39e96f9b25d2e10ef8231c0899530917373774f4c4c26bfe674a7f9accc6d2e639dd0c3baab25bd543029b4740034a8ad75
7
+ data.tar.gz: 15bb34106c90a0f72f3e05fa5075636f2e4e28839b8a1820695087c3c2c1707e3aad9c6c2825f630f5db8e18753f8780484af2fa5005ce50a46ab67224aae114
@@ -4,7 +4,7 @@ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
4
 
5
5
  Gem::Specification.new do |spec|
6
6
  spec.name = 'honeybee-openstudio'
7
- spec.version = '2.6.2'
7
+ spec.version = '2.6.7'
8
8
  spec.authors = ['Tanushree Charan', 'Dan Macumber', 'Chris Mackey', 'Mostapha Sadeghipour Roudsari']
9
9
  spec.email = ['tanushree.charan@nrel.gov', 'chris@ladybug.tools']
10
10
 
@@ -21,4 +21,4 @@ else
21
21
  end
22
22
 
23
23
  # include the honeybee-openstudio-gem
24
- gem 'honeybee-openstudio', '2.5.3'
24
+ gem 'honeybee-openstudio', '2.6.4'
@@ -55,7 +55,12 @@ module FromHoneybee
55
55
  os_construction = OpenStudio::Model::ConstructionAirBoundary.new(openstudio_model)
56
56
  os_construction.setName(@hash[:identifier])
57
57
  os_construction.setSolarAndDaylightingMethod('GroupedZones')
58
- os_construction.setRadiantExchangeMethod('GroupedZones')
58
+ # REMOVE: Remove the use of IRTSurface once the AFN works with GroupedZone air walls
59
+ if !$use_simple_vent # we're using the AFN!
60
+ os_construction.setRadiantExchangeMethod('IRTSurface')
61
+ else
62
+ os_construction.setRadiantExchangeMethod('GroupedZones')
63
+ end
59
64
  os_construction.setAirExchangeMethod('None')
60
65
 
61
66
  os_construction
@@ -54,6 +54,7 @@ module FromHoneybee
54
54
  def initialize(hash = {})
55
55
  super(hash)
56
56
  raise "Incorrect model type '#{@type}'" unless @type == 'Room'
57
+ @unique_space_type = nil
57
58
  end
58
59
 
59
60
  def defaults
@@ -66,6 +67,33 @@ module FromHoneybee
66
67
  nil
67
68
  end
68
69
 
70
+ def get_unique_space_type(openstudio_model, os_space)
71
+ # get a space type that is unique to the room
72
+ if @unique_space_type.nil?
73
+ space_type = os_space.spaceType
74
+ unless space_type.empty?
75
+ # copy the space type that is already assigned to the room
76
+ space_type_object = space_type.get
77
+ space_type_mod_obj = space_type_object.clone(openstudio_model)
78
+ new_space_type = space_type_mod_obj.to_SpaceType.get
79
+ else
80
+ # create a new space type as there is currently none assigned to the room
81
+ new_space_type = OpenStudio::Model::SpaceType.new(openstudio_model)
82
+ end
83
+ # give the space type a new unique name and assign it to the room
84
+ st_name = space_type_object.name
85
+ unless space_type.empty?
86
+ st_name = st_name.get
87
+ else
88
+ st_name = 'CustomSpaceType'
89
+ end
90
+ new_space_type.setName(st_name + '_' + @hash[:identifier])
91
+ os_space.setSpaceType(new_space_type)
92
+ @unique_space_type = new_space_type
93
+ end
94
+ @unique_space_type
95
+ end
96
+
69
97
  def to_openstudio(openstudio_model)
70
98
  # create the space and thermal zone
71
99
  os_space = OpenStudio::Model::Space.new(openstudio_model)
@@ -213,88 +241,75 @@ module FromHoneybee
213
241
  @hash[:outdoor_shades].each do |outdoor_shade|
214
242
  add_shade_to_group(openstudio_model, os_shd_group, outdoor_shade)
215
243
  end
216
- end
244
+ end
217
245
 
218
246
  #check whether there are any load objects on the room overriding the programtype
219
247
  if @hash[:properties][:energy][:people]
220
- people = openstudio_model.getPeopleByName(@hash[:properties][:energy][:people][:identifier])
221
- unless people.empty?
222
- people_object = people.get
223
- people_object.setSpace(os_space)
224
- else
225
- people_space = PeopleAbridged.new(@hash[:properties][:energy][:people])
226
- os_people_space = people_space.to_openstudio(openstudio_model)
227
- os_people_space.setSpace(os_space)
248
+ unique_program = get_unique_space_type(openstudio_model, os_space)
249
+ unique_program_ppl = unique_program.people
250
+ unless unique_program_ppl.empty? # remove the previous load definition
251
+ unique_program_ppl[0].remove()
228
252
  end
253
+ custom_people = PeopleAbridged.new(@hash[:properties][:energy][:people])
254
+ os_custom_people = custom_people.to_openstudio(openstudio_model)
255
+ os_custom_people.setSpaceType(unique_program) # assign the new load definition
229
256
  end
230
257
 
231
258
  # assign lighting if it exists
232
259
  if @hash[:properties][:energy][:lighting]
233
- lighting = openstudio_model.getLightsByName(@hash[:properties][:energy][:lighting][:identifier])
234
- unless lighting.empty?
235
- lighting_object = lighting.get
236
- lighting_object.setSpace(os_space)
237
- else
238
- lighting_space = LightingAbridged.new(@hash[:properties][:energy][:lighting])
239
- os_lighting_space = lighting_space.to_openstudio(openstudio_model)
240
- os_lighting_space.setSpace(os_space)
260
+ unique_program = get_unique_space_type(openstudio_model, os_space)
261
+ unique_program_lght = unique_program.lights
262
+ unless unique_program_lght.empty? # remove the previous load definition
263
+ unique_program_lght[0].remove()
241
264
  end
265
+ custom_lighting = LightingAbridged.new(@hash[:properties][:energy][:lighting])
266
+ os_custom_lighting = custom_lighting.to_openstudio(openstudio_model)
267
+ os_custom_lighting.setSpaceType(unique_program) # assign the new load definition
242
268
  end
243
269
 
244
270
  # assign electric equipment if it exists
245
271
  if @hash[:properties][:energy][:electric_equipment]
246
- electric_equipment = openstudio_model.getElectricEquipmentByName(
247
- @hash[:properties][:energy][:electric_equipment][:identifier])
248
- unless electric_equipment.empty?
249
- electric_equipment_object = electric_equipment.get
250
- electric_equipment_object.setSpace(os_space)
251
- else
252
- electric_equipment_space = ElectricEquipmentAbridged.new(@hash[:properties][:energy][:electric_equipment])
253
- os_electric_equipment_space = electric_equipment_space.to_openstudio(openstudio_model)
254
- os_electric_equipment_space.setSpace(os_space)
272
+ unique_program = get_unique_space_type(openstudio_model, os_space)
273
+ unique_program_ele = unique_program.electricEquipment
274
+ unless unique_program_ele.empty? # remove the previous load definition
275
+ unique_program_ele[0].remove()
255
276
  end
277
+ custom_electric_equipment = ElectricEquipmentAbridged.new(@hash[:properties][:energy][:electric_equipment])
278
+ os_custom_electric_equipment = custom_electric_equipment.to_openstudio(openstudio_model)
279
+ os_custom_electric_equipment.setSpaceType(unique_program) # assign the new load definition
256
280
  end
257
-
281
+
258
282
  # assign gas equipment if it exists
259
283
  if @hash[:properties][:energy][:gas_equipment]
260
- gas_equipment = openstudio_model.getGasEquipmentByName(
261
- @hash[:properties][:energy][:gas_equipment][:identifier])
262
- unless gas_equipment.empty?
263
- gas_equipment_object = gas_equipment.get
264
- gas_equipment_object.setSpace(os_space)
265
- else
266
- gas_equipment_space = GasEquipmentAbridged.new(@hash[:properties][:energy][:gas_equipment])
267
- os_gas_equipment_space = gas_equipment_space.to_openstudio(openstudio_model)
268
- os_gas_equipment_space.setSpace(os_space)
284
+ unique_program = get_unique_space_type(openstudio_model, os_space)
285
+ unique_program_gas = unique_program.gasEquipment
286
+ unless unique_program_gas.empty? # remove the previous load definition
287
+ unique_program_gas[0].remove()
269
288
  end
289
+ custom_gas_equipment = GasEquipmentAbridged.new(@hash[:properties][:energy][:gas_equipment])
290
+ os_custom_gas_equipment = custom_gas_equipment.to_openstudio(openstudio_model)
291
+ os_custom_gas_equipment.setSpaceType(unique_program) # assign the new load definition
270
292
  end
271
293
 
272
294
  # assign infiltration if it exists
273
295
  if @hash[:properties][:energy][:infiltration] && $use_simple_vent # only use infiltration with simple ventilation
274
- infiltration = openstudio_model.getSpaceInfiltrationDesignFlowRateByName(
275
- @hash[:properties][:energy][:infiltration][:identifier])
276
- unless infiltration.empty?
277
- infiltration_object = infiltration.get
278
- infiltration_object.setSpace(os_space)
279
- else
280
- infiltration_space = InfiltrationAbridged.new(@hash[:properties][:energy][:infiltration])
281
- os_infiltration_space = infiltration_space.to_openstudio(openstudio_model)
282
- os_infiltration_space.setSpace(os_space)
296
+ unique_program = get_unique_space_type(openstudio_model, os_space)
297
+ unique_program_inf = unique_program.spaceInfiltrationDesignFlowRates
298
+ unless unique_program_inf.empty? # remove the previous load definition
299
+ unique_program_inf[0].remove()
283
300
  end
301
+ custom_infiltration = InfiltrationAbridged.new(@hash[:properties][:energy][:infiltration])
302
+ os_custom_infiltration = custom_infiltration.to_openstudio(openstudio_model)
303
+ os_custom_infiltration.setSpaceType(unique_program) # assign the new load definition
284
304
  end
285
-
305
+
286
306
  # assign ventilation if it exists
287
307
  if @hash[:properties][:energy][:ventilation]
288
- ventilation = openstudio_model.getDesignSpecificationOutdoorAirByName(
289
- @hash[:properties][:energy][:ventilation][:identifier])
290
- unless ventilation.empty?
291
- ventilation_object = ventilation.get
292
- ventilation_object.setSpace(os_space)
293
- else
294
- ventilation_space = VentilationAbridged.new(@hash[:properties][:energy][:ventilation])
295
- os_ventilation_space = ventilation_space.to_openstudio(openstudio_model)
296
- os_space.setDesignSpecificationOutdoorAir(os_ventilation_space)
297
- end
308
+ unique_program = get_unique_space_type(openstudio_model, os_space)
309
+ unique_program.resetDesignSpecificationOutdoorAir()
310
+ custom_ventilation = VentilationAbridged.new(@hash[:properties][:energy][:ventilation])
311
+ os_custom_ventilation = custom_ventilation.to_openstudio(openstudio_model)
312
+ unique_program.setDesignSpecificationOutdoorAir(os_custom_ventilation)
298
313
  end
299
314
 
300
315
  # assign setpoint if it exists
@@ -533,12 +533,14 @@ module FromHoneybee
533
533
  system_type = hvac[:type]
534
534
  if system_type == 'IdealAirSystemAbridged'
535
535
  ideal_air_system = IdealAirSystemAbridged.new(hvac)
536
- os_ideal_air_system = ideal_air_system.to_openstudio(@openstudio_model)
537
536
  hvac['rooms'].each do |room_id|
537
+ os_ideal_air = ideal_air_system.to_openstudio(@openstudio_model)
538
+ # enforce a strict naming system for each zone so results can be matched
539
+ os_ideal_air.setName(room_id + ' Ideal Loads Air System')
538
540
  zone_get = @openstudio_model.getThermalZoneByName(room_id)
539
541
  unless zone_get.empty?
540
542
  os_thermal_zone = zone_get.get
541
- os_ideal_air_system.addToThermalZone(os_thermal_zone)
543
+ os_ideal_air.addToThermalZone(os_thermal_zone)
542
544
  end
543
545
  end
544
546
  elsif TemplateHVAC.types.include?(system_type)
@@ -138,7 +138,7 @@ module FromHoneybee
138
138
  openstudio_schedule_rule.setApplyFriday(rule[:apply_friday])
139
139
  openstudio_schedule_rule.setApplySaturday(rule[:apply_saturday])
140
140
  year_description = openstudio_model.getYearDescription
141
- start_date = year_description.makeDate(rule[:start_date][0], rule[:start_date][1])
141
+ start_date = year_description.makeDate(rule[:start_date][0], rule[:start_date][1])
142
142
  end_date = year_description.makeDate(rule[:end_date][0], rule[:end_date][1])
143
143
  openstudio_schedule_rule.setStartDate(start_date)
144
144
  openstudio_schedule_rule.setEndDate(end_date)
@@ -288,7 +288,18 @@ module FromHoneybee
288
288
  @hash[:run_period][:daylight_saving_time][:end_date][1])
289
289
  end
290
290
 
291
- # TODO: set the holidays once they are available in OpenStudio SDK
291
+ # Set the holidays
292
+ if @hash[:run_period][:holidays]
293
+ @hash[:run_period][:holidays].each do |hol|
294
+ begin
295
+ os_hol = OpenStudio::Model::RunPeriodControlSpecialDays.new(
296
+ OpenStudio::MonthOfYear.new(hol[0]), hol[1], @openstudio_model)
297
+ os_hol.setDuration(1)
298
+ os_hol.setSpecialDayType('Holiday')
299
+ rescue NoMethodError # REMOVE: Once the upgrade to OpenStudio 3.0 is official
300
+ end
301
+ end
302
+ end
292
303
  end
293
304
 
294
305
  # set the simulation timestep
@@ -98,6 +98,20 @@ module FromHoneybee
98
98
  @@sensor_count = @@sensor_count + 1
99
99
  in_air_temp.setName(in_sensor_name)
100
100
 
101
+ # set up a schedule sensor if there's a schedule specified
102
+ if @hash[:schedule]
103
+ vent_sch = openstudio_model.getScheduleByName(@hash[:schedule])
104
+ unless vent_sch.empty? # schedule not specified
105
+ sch_var = OpenStudio::Model::OutputVariable.new('Schedule Value', openstudio_model)
106
+ sch_var.setReportingFrequency('Timestep')
107
+ sch_var.setKeyValue(@hash[:schedule])
108
+ sch_sens = OpenStudio::Model::EnergyManagementSystemSensor.new(openstudio_model, sch_var)
109
+ sch_sensor_name = replace_ems_special_characters(os_zone_name) + '_Sensor' + @@sensor_count.to_s
110
+ @@sensor_count = @@sensor_count + 1
111
+ sch_sens.setName(sch_sensor_name)
112
+ end
113
+ end
114
+
101
115
  # create the actuators for each of the operaable windows
102
116
  actuator_names = []
103
117
  vent_opening_surfaces.each do |vent_srf|
@@ -140,6 +154,10 @@ module FromHoneybee
140
154
  if delta_in_out && delta_in_out != defaults[:delta_temperature][:default]
141
155
  logic_statements << '((' + in_sensor_name + ' - Outdoor_Sensor) > ' + delta_in_out.to_s + ')'
142
156
  end
157
+ # check the schedule for ventilation
158
+ if sch_sensor_name
159
+ logic_statements << '(' + sch_sensor_name + ' > 0)'
160
+ end
143
161
  # create the complete logic statement for opening windows
144
162
  if logic_statements.empty?
145
163
  complete_logic = 'IF (Outdoor_Sensor < 100)' # no logic has been provided; always open windows
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: honeybee-openstudio
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.2
4
+ version: 2.6.7
5
5
  platform: ruby
6
6
  authors:
7
7
  - Tanushree Charan
@@ -11,7 +11,7 @@ authors:
11
11
  autorequire:
12
12
  bindir: exe
13
13
  cert_chain: []
14
- date: 2020-09-02 00:00:00.000000000 Z
14
+ date: 2020-10-23 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: bundler