diff --git a/lib/buildingsync/model_articulation/spatial_element.rb b/lib/buildingsync/model_articulation/spatial_element.rb index a5741f00..df3f1a30 100644 --- a/lib/buildingsync/model_articulation/spatial_element.rb +++ b/lib/buildingsync/model_articulation/spatial_element.rb @@ -189,40 +189,52 @@ def sets_occupancy_bldg_system_types(occ_type) def process_bldg_and_system_type(building_and_system_types, occupancy_classification, total_floor_area, total_number_floors) OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.SpatialElement.process_bldg_and_system_type', "Element ID: #{xget_id} started with occupancy_classification #{occupancy_classification} and total floor area: #{total_floor_area}") puts "Element ID: #{xget_id} started with occupancy_classification #{occupancy_classification} and total floor area: #{total_floor_area}" - min_floor_area_correct = false - max_floor_area_correct = false - building_and_system_types[:"#{occupancy_classification}"]&.each do |occ_type| - if !occ_type[:standards_building_type].nil? - if occ_type[:min_floor_area] || occ_type[:max_floor_area] - if occ_type[:min_floor_area] && occ_type[:min_floor_area].to_f < total_floor_area - min_floor_area_correct = true - end - if occ_type[:max_floor_area] && occ_type[:max_floor_area].to_f > total_floor_area - max_floor_area_correct = true - end - if (min_floor_area_correct && max_floor_area_correct) || (!occ_type[:min_floor_area] && max_floor_area_correct) || (min_floor_area_correct && !occ_type[:max_floor_area]) - puts "selected the following standards_building_type: #{occ_type[:standards_building_type]}" - return sets_occupancy_bldg_system_types(occ_type) - end - elsif occ_type[:min_number_floors] || occ_type[:max_number_floors] - if occ_type[:min_number_floors] && occ_type[:min_number_floors].to_i <= total_number_floors - puts "selected the following standards_building_type: #{occ_type[:standards_building_type]}" - return sets_occupancy_bldg_system_types(occ_type) - elsif occ_type[:max_number_floors] && occ_type[:max_number_floors].to_i > total_number_floors - puts "selected the following standards_building_type: #{occ_type[:standards_building_type]}" - return sets_occupancy_bldg_system_types(occ_type) - end - else - # otherwise we assume the first one is correct and we select this + + # if building_and_system_types doesn't contain occupancy_classification, there's nothing we can do. + occ_types = building_and_system_types[:"#{occupancy_classification}"] + if occ_types.nil? + raise "BuildingSync Occupancy type #{occupancy_classification} is not available in the building_and_system_types.json dictionary" + end + + # if theres only one, we chose it indiscriminately + # TODO: idk if we should do this but its what the tests want + if occ_types.length == 1 + return sets_occupancy_bldg_system_types(occ_types[0]) + end + + # Try on each occ_type in the occupancy_classification for size + occ_types.each do |occ_type| + # if occ_type has a specified floor area range, see if it matches up + if occ_type[:min_floor_area] || occ_type[:max_floor_area] + min_floor_area = occ_type[:min_floor_area].nil? ? + nil : + OpenStudio.convert(occ_type[:min_floor_area].to_f, 'ft^2', 'm^2').get + max_floor_area = occ_type[:max_floor_area].nil? ? + nil : + OpenStudio.convert(occ_type[:max_floor_area].to_f, 'ft^2', 'm^2').get + + too_small = min_floor_area && total_floor_area < min_floor_area + too_big = max_floor_area && total_floor_area >= max_floor_area + if !too_big && !too_small + puts "selected the following standards_building_type: #{occ_type[:standards_building_type]}" + return sets_occupancy_bldg_system_types(occ_type) + end + + # else, if occ_type a specified floor number range, see if it matches up + elsif occ_type[:min_number_floors] || occ_type[:max_number_floors] + min_number_floors = occ_type[:min_number_floors].nil? ? nil : occ_type[:min_number_floors].to_i + max_number_floors = occ_type[:max_number_floors].nil? ? nil : occ_type[:max_number_floors].to_i + + too_small = min_number_floors && total_number_floors < min_number_floors + too_big = max_number_floors && total_number_floors >= max_number_floors + if !too_big && !too_small puts "selected the following standards_building_type: #{occ_type[:standards_building_type]}" return sets_occupancy_bldg_system_types(occ_type) end - else - # otherwise we assume the first one is correct and we select this - return sets_occupancy_bldg_system_types(occ_type) end end - raise "BuildingSync Occupancy type #{occupancy_classification} is not available in the building_and_system_types.json dictionary" + + # no occ_type fit! We must give up return false end diff --git a/spec/tests/model_articulation_test/site_spec.rb b/spec/tests/model_articulation_test/site_spec.rb index 5f0a594b..e53ca523 100644 --- a/spec/tests/model_articulation_test/site_spec.rb +++ b/spec/tests/model_articulation_test/site_spec.rb @@ -86,6 +86,24 @@ expect(site.get_system_type == 'PSZ-AC with gas coil heat').to be true end + it 'Should return the correct building type based on size' do + g = BuildingSync::Generator.new + site = g.create_minimum_site('Office', '1954', 'Gross', '10000') + expect(site.get_building_type == 'SmallOffice').to be true + + g = BuildingSync::Generator.new + site = g.create_minimum_site('Office', '1954', 'Gross', '20000') + expect(site.get_building_type == 'MediumOffice').to be true + + g = BuildingSync::Generator.new + site = g.create_minimum_site('Office', '1954', 'Gross', '25000') + expect(site.get_building_type == 'MediumOffice').to be true + + g = BuildingSync::Generator.new + site = g.create_minimum_site('Office', '1954', 'Gross', '75000') + expect(site.get_building_type == 'LargeOffice').to be true + end + it 'Should return the correct building type' do g = BuildingSync::Generator.new site = g.create_minimum_site('Retail', '1954', 'Gross', '69452') diff --git a/spec/tests/translator_sizing_run_spec.rb b/spec/tests/translator_sizing_run_spec.rb index c4d16864..59fb2023 100644 --- a/spec/tests/translator_sizing_run_spec.rb +++ b/spec/tests/translator_sizing_run_spec.rb @@ -145,7 +145,7 @@ # Trace/BPT trap: 5 gets hit for following 2 lines # ['Golden Test File.xml', CA_TITLE24, nil, 'v2.4.0', "Error, cannot find local component for: fa8c9ff0-edc4-0131-a9f8-48e0eb16a403. Please try a different weather file."], # ['Golden Test File.xml', ASHRAE90_1, nil, 'v2.4.0', "Error, cannot find local component for: fa8c9ff0-edc4-0131-a9f8-48e0eb16a403. Please try a different weather file."], - ['Golden Test File.xml', CA_TITLE24, File.join(SPEC_WEATHER_DIR, 'USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw'), 'v2.4.0', "undefined method `add_internal_loads' for nil:NilClass"], + ['Golden Test File.xml', CA_TITLE24, File.join(SPEC_WEATHER_DIR, 'USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw'), 'v2.4.0', "BuildingSync.Building.determine_open_studio_standard: ERROR: Did not find a class called 'CBES T24 2008_LargeOffice' to create in CaliforniaTitle24", false], ['Golden Test File.xml', ASHRAE90_1, File.join(SPEC_WEATHER_DIR, 'USA_IL_Chicago-OHare.Intl.AP.725300_TMY3.epw'), 'v2.4.0', "undefined method `add_internal_loads' for nil:NilClass"], # #####################################