honeybee-openstudio 2.33.6 → 2.34.0

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: fb5fa50e1c896889d81a5addfacf5db33e384f9a9c40f32f09c5964e9da2de76
4
- data.tar.gz: a6d221fad4de2c03ad3de093b8e430511744e1b5111e372ecf4ffea75d8b6851
3
+ metadata.gz: 0db23d24e0621410e05134519babfe4ae11c803b8df518b3e587afb836eb0304
4
+ data.tar.gz: b2984946072c3c094057e5e0f97dd52c15012290fa6953d1b245d95c9f9f6a06
5
5
  SHA512:
6
- metadata.gz: 04a7362bdc83c91137e6cf6c7bd7f9a8c4d887f39b5b1f7a54d46e86e98fe4c52a1c3690d432fac3f3135c53a85de257885b567156febb88efc9a888669a87a8
7
- data.tar.gz: 98e3efbfda5be87a15b3a8cd8f062e38cebc60e872d71439981fc5307df4b72bcd9adaa408d2c83357979f4301ff845930d185a51deb42c9edad831387660582
6
+ metadata.gz: e948fb628063eb9f0d7bc6477aaa3e05b425cc68ac0e3127472a7a8df34f7050d70901538f39656aaa39198465a6515ccc9697d632d38249ac1914e218f9dafc
7
+ data.tar.gz: 46cf5d6d1619847528ce5ae15b592dab6c16492b87deb13ca38c5270af7918af581e18891b6062c3904f3b9b0322812815e53cb633dde1699f2b580461650005
@@ -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.33.6'
7
+ spec.version = '2.34.0'
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
 
@@ -36,6 +36,7 @@ require 'to_openstudio'
36
36
 
37
37
  require 'fileutils'
38
38
  require 'pathname'
39
+ require 'json'
39
40
 
40
41
  # start the measure
41
42
  class FromHoneybeeModel < OpenStudio::Measure::ModelMeasure
@@ -87,17 +88,19 @@ class FromHoneybeeModel < OpenStudio::Measure::ModelMeasure
87
88
  return false
88
89
  end
89
90
 
91
+ # get the input arguments
90
92
  model_json = runner.getStringArgumentValue('model_json', user_arguments)
91
93
  schedule_csv_dir = runner.getStringArgumentValue('schedule_csv_dir', user_arguments)
92
94
  include_datetimes = runner.getBoolArgumentValue('include_datetimes', user_arguments)
93
95
 
96
+ # load the HBJSON file
94
97
  if !File.exist?(model_json)
95
98
  runner.registerError("Cannot find file '#{model_json}'")
96
99
  return false
97
100
  end
98
-
99
101
  honeybee_model = Honeybee::Model.read_from_disk(model_json)
100
102
 
103
+ # setup the schedule directory
101
104
  if schedule_csv_dir && !schedule_csv_dir.empty?
102
105
  schedule_csv_dir = Pathname.new(schedule_csv_dir).cleanpath
103
106
  if !Dir.exist?(schedule_csv_dir)
@@ -107,11 +110,88 @@ class FromHoneybeeModel < OpenStudio::Measure::ModelMeasure
107
110
  honeybee_model.set_schedule_csv_dir(schedule_csv_dir, include_datetimes)
108
111
  end
109
112
 
113
+ # translate the Honeybee Model to OSM
110
114
  STDOUT.flush
111
115
  honeybee_model.to_openstudio_model(model)
112
116
  STDOUT.flush
113
117
 
118
+ # if there are any detailed HVACs, incorproate them into the OSM
114
119
  generated_files_dir = "#{runner.workflow.absoluteRootDir}/generated_files"
120
+ unless $detailed_hvac_hash.nil? || $detailed_hvac_hash.empty?
121
+ runner.registerInfo("Translating Detailed HVAC systems in '#{generated_files_dir}'")
122
+ if $ironbug_exe.nil?
123
+ runner.registerError("No Ironbug installation was found on the system.")
124
+ end
125
+ FileUtils.mkdir_p(generated_files_dir)
126
+ $detailed_hvac_hash.each do |hvac_id, hvac_spec|
127
+ # write the JSON and OSM files
128
+ hvac_json_path = generated_files_dir + '/' + hvac_id + '.json'
129
+ osm_path = generated_files_dir + '/' + hvac_id + '.osm'
130
+ File.open(hvac_json_path, 'w') do |f|
131
+ f.write(hvac_spec.to_json)
132
+ end
133
+ model.save(osm_path, true)
134
+ # call the Ironbug console to add the HVAC to the OSM
135
+ ironbug_exe = '"' + $ironbug_exe + '"'
136
+ system(ironbug_exe + ' "' + osm_path + '" "' + hvac_json_path + '"')
137
+ # load the new model
138
+ translator = OpenStudio::OSVersion::VersionTranslator.new
139
+ o_model = translator.loadModel(osm_path)
140
+ if o_model.empty?
141
+ runner.registerError("Could not load Ironbug model from '" + osm_path.to_s + "'.")
142
+ return false
143
+ end
144
+ new_model = o_model.get
145
+ # replace the current model with the contents of the loaded model
146
+ handles = OpenStudio::UUIDVector.new
147
+ model.objects.each do |obj|
148
+ handles << obj.handle
149
+ end
150
+ model.removeObjects(handles)
151
+ # add new file to empty model
152
+ model.addObjects(new_model.toIdfFile.objects)
153
+ end
154
+ end
155
+
156
+ # if an efficiency standard has been set on the model, then run sizing and set everything
157
+ building = model.getBuilding
158
+ unless building.standardsTemplate.empty?
159
+ puts 'Autosizing HVAC systems and assigning efficiencies'
160
+ standard_id = building.standardsTemplate.get
161
+ require 'openstudio-standards'
162
+ standard = Standard.build(standard_id)
163
+ # Set the heating and cooling sizing parameters
164
+ standard.model_apply_prm_sizing_parameters(model)
165
+ # Perform a sizing run
166
+ if standard.model_run_sizing_run(model, "#{Dir.pwd}/SR1") == false
167
+ log_messages_to_runner(runner, debug = true)
168
+ return false
169
+ end
170
+ # If there are any multizone systems, reset damper positions
171
+ # to achieve a 60% ventilation effectiveness minimum for the system
172
+ # following the ventilation rate procedure from 62.1
173
+ standard.model_apply_multizone_vav_outdoor_air_sizing(model)
174
+ # get the climate zone
175
+ climate_zone_obj = model.getClimateZones.getClimateZone('ASHRAE', 2006)
176
+ if climate_zone_obj.empty
177
+ climate_zone_obj = model.getClimateZones.getClimateZone('ASHRAE', 2013)
178
+ end
179
+ climate_zone = climate_zone_obj.value
180
+ # get the building type
181
+ bldg_type = nil
182
+ unless building.standardsBuildingType.empty?
183
+ bldg_type = building.standardsBuildingType.get
184
+ end
185
+ # Apply the prototype HVAC assumptions
186
+ standard.model_apply_prototype_hvac_assumptions(model, bldg_type, climate_zone)
187
+ # Apply the HVAC efficiency standard
188
+ standard.model_apply_hvac_efficiency_standard(model, climate_zone)
189
+ puts 'Done with autosizing HVAC systems!'
190
+ end
191
+
192
+ puts 'Done with Model translation!'
193
+
194
+ # copy the CSV schedules into the directory where EnergyPlus can find them
115
195
  if schedule_csv_dir && !schedule_csv_dir.empty?
116
196
  if Dir.exist?(schedule_csv_dir)
117
197
  runner.registerInfo("Copying exported schedules from '#{schedule_csv_dir}' to '#{generated_files_dir}'")
@@ -308,6 +308,10 @@ class OpenStudio::Model::Model
308
308
  when 'Furnace'
309
309
  # includes ventilation, whereas residential forced air furnace does not.
310
310
  standard.model_add_hvac_system(self, 'Forced Air Furnace', ht = 'NaturalGas', znht = nil, cl = nil, heated_zones)
311
+
312
+ when 'Furnace_Electric'
313
+ # includes ventilation, whereas residential forced air furnace does not.
314
+ standard.model_add_hvac_system(self, 'Forced Air Furnace', ht = 'Electricity', znht = nil, cl = nil, heated_zones)
311
315
 
312
316
  when 'GasHeaters'
313
317
  standard.model_add_hvac_system(self, 'Unit Heaters', ht = 'NaturalGas', znht = nil, cl = nil, heated_zones)
@@ -90,26 +90,28 @@ module Honeybee
90
90
 
91
91
  # Get the air loops and assign the display name to the air loop name if it exists
92
92
  os_air_loops = []
93
- air_loops = openstudio_model.getAirLoopHVACs
94
- unless air_loops.length == $air_loop_count # check if any new loops were added
95
- $air_loop_count = air_loops.length
96
- zones.each do |zon|
97
- os_air_terminal = zon.airLoopHVACTerminal
98
- unless os_air_terminal.empty?
99
- os_air_terminal = os_air_terminal.get
100
- os_air_loop_opt = os_air_terminal.airLoopHVAC
101
- unless os_air_loop_opt.empty?
102
- os_air_loop = os_air_loop_opt.get
103
- os_air_loops << os_air_loop
104
- loop_name = os_air_loop.name
105
- unless loop_name.empty?
106
- # set the name of the air loop to align with the HVAC name
107
- if @hash[:display_name]
108
- clean_name = @hash[:display_name].to_s.gsub(/[^.A-Za-z0-9_-] /, " ")
109
- os_air_loop.setName(clean_name + ' - ' + loop_name.get)
93
+ unless equipment_type.to_s.include? 'Furnace'
94
+ air_loops = openstudio_model.getAirLoopHVACs
95
+ unless air_loops.length == $air_loop_count
96
+ $air_loop_count = air_loops.length
97
+ zones.each do |zon|
98
+ os_air_terminal = zon.airLoopHVACTerminal
99
+ unless os_air_terminal.empty?
100
+ os_air_terminal = os_air_terminal.get
101
+ os_air_loop_opt = os_air_terminal.airLoopHVAC
102
+ unless os_air_loop_opt.empty?
103
+ os_air_loop = os_air_loop_opt.get
104
+ os_air_loops << os_air_loop
105
+ loop_name = os_air_loop.name
106
+ unless loop_name.empty?
107
+ # set the name of the air loop to align with the HVAC name
108
+ if @hash[:display_name]
109
+ clean_name = @hash[:display_name].to_s.gsub(/[^.A-Za-z0-9_-] /, " ")
110
+ os_air_loop.setName(clean_name + ' - ' + loop_name.get)
111
+ end
110
112
  end
113
+ break if !equipment_type.include? 'PSZ' # multiple air loops have been added
111
114
  end
112
- break if !equipment_type.include? 'PSZ' # multiple air loops have been added
113
115
  end
114
116
  end
115
117
  end
@@ -197,6 +199,21 @@ module Honeybee
197
199
  end
198
200
  end
199
201
 
202
+ # change furnace to electric if specified
203
+ if equipment_type.to_s.include? 'Furnace_Electric'
204
+ openstudio_model.getAirLoopHVACUnitarySystems.sort.each do |obj|
205
+ unless obj.heatingCoil.empty?
206
+ old_coil = obj.heatingCoil.get
207
+ heat_coil = OpenStudio::Model::CoilHeatingElectric.new(openstudio_model)
208
+ unless old_coil.name.empty?
209
+ heat_coil.setName(old_coil.name.get)
210
+ end
211
+ obj.setHeatingCoil(heat_coil)
212
+ old_coil.remove()
213
+ end
214
+ end
215
+ end
216
+
200
217
  # assign the economizer type if there's an air loop and the economizer is specified
201
218
  if @hash[:economizer_type] && !os_air_loops.empty?
202
219
  os_air_loops.each do |os_air_loop|
@@ -92,10 +92,6 @@ module Honeybee
92
92
  # create all openstudio objects in the model
93
93
  create_openstudio_objects(log_report)
94
94
 
95
- if log_report
96
- puts 'Done with Model translation!'
97
- end
98
-
99
95
  @openstudio_model
100
96
  end
101
97
 
@@ -105,7 +101,9 @@ module Honeybee
105
101
  def create_openstudio_objects(log_report=true)
106
102
  # assign a standards building type so that David's measures can run
107
103
  building = @openstudio_model.getBuilding
108
- building.setStandardsBuildingType('MediumOffice')
104
+ if building.standardsBuildingType.empty?
105
+ building.setStandardsBuildingType('MediumOffice')
106
+ end
109
107
 
110
108
  # initialize a global variable for whether the AFN is used instead of simple ventilation
111
109
  $use_simple_vent = true
@@ -127,6 +125,8 @@ module Honeybee
127
125
  $programtype_setpoint_hash = Hash.new # hash to track Setpoint objects
128
126
  $interior_afn_srf_hash = Hash.new # track whether an adjacent surface is already in the AFN
129
127
  $shw_for_plant = nil # track whether a hot water plant is needed
128
+ $detailed_hvac_hash = Hash.new # track the detailed HVAC systems that have been assigned
129
+ $ironbug_exe = nil # ironbug executable; will be overwritten by any detailed HVACs
130
130
 
131
131
  # create all of the non-geometric model elements
132
132
  if @hash[:properties].key?(:energy)
@@ -572,6 +572,11 @@ module Honeybee
572
572
  end
573
573
  end
574
574
  end
575
+ elsif system_type == 'DetailedHVAC'
576
+ $detailed_hvac_hash[hvac[:identifier]] = hvac[:specification]
577
+ unless hvac[:ironbug_exe].nil?
578
+ $ironbug_exe = hvac[:ironbug_exe]
579
+ end
575
580
  elsif TemplateHVAC.types.include?(system_type)
576
581
  template_system = TemplateHVAC.new(hvac)
577
582
  template_system.to_openstudio(@openstudio_model, hvac['rooms'])
@@ -35,6 +35,16 @@ require 'openstudio'
35
35
 
36
36
  module Honeybee
37
37
  class SimulationParameter
38
+ @@standard_mapper = {
39
+ DOE_Ref_Pre_1980: 'DOE Ref Pre-1980',
40
+ DOE_Ref_1980_2004: 'DOE Ref 1980-2004',
41
+ ASHRAE_2004: '90.1-2004',
42
+ ASHRAE_2007: '90.1-2007',
43
+ ASHRAE_2010: '90.1-2010',
44
+ ASHRAE_2013: '90.1-2013',
45
+ ASHRAE_2016: '90.1-2016',
46
+ ASHRAE_2019: '90.1-2019'
47
+ }
38
48
 
39
49
  # convert to openstudio model, clears errors and warnings
40
50
  def to_openstudio_model(openstudio_model=nil, log_report=false)
@@ -226,6 +236,22 @@ module Honeybee
226
236
  climate_zone_objs.setClimateZone('ASHRAE', cz)
227
237
  end
228
238
 
239
+ # note any efficency standards that have been assigned to the
240
+ if @hash[:sizing_parameter]
241
+ if @hash[:sizing_parameter][:efficiency_standard]
242
+ std_gem_standard = @@standard_mapper[@hash[:sizing_parameter][:efficiency_standard].to_sym]
243
+ building = @openstudio_model.getBuilding
244
+ building.setStandardsTemplate(std_gem_standard)
245
+ end
246
+ if @hash[:sizing_parameter][:climate_zone]
247
+ climate_zone_objs.setClimateZone('ASHRAE', @hash[:sizing_parameter][:climate_zone])
248
+ end
249
+ if @hash[:sizing_parameter][:building_type]
250
+ building = @openstudio_model.getBuilding
251
+ building.setStandardsBuildingType(@hash[:sizing_parameter][:building_type])
252
+ end
253
+ end
254
+
229
255
  # set Outputs for the simulation
230
256
  if @hash[:output]
231
257
  if @hash[:output][:outputs]
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.33.6
4
+ version: 2.34.0
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: 2023-01-18 00:00:00.000000000 Z
14
+ date: 2023-02-11 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: json_pure