honeybee-openstudio 2.33.6 → 2.34.0

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.
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