Class: BuildingSync::SpatialElement
- Inherits:
-
Object
- Object
- BuildingSync::SpatialElement
- Defined in:
- lib/buildingsync/model_articulation/spatial_element.rb
Overview
base class for objects that will configure workflows based on building sync files
Direct Known Subclasses
Instance Attribute Summary collapse
-
#space_types ⇒ Object
readonly
Returns the value of attribute space_types.
-
#standards_building_type ⇒ Object
readonly
Returns the value of attribute standards_building_type.
-
#system_type ⇒ Object
readonly
Returns the value of attribute system_type.
-
#total_floor_area ⇒ Object
readonly
Returns the value of attribute total_floor_area.
Instance Method Summary collapse
-
#add_user_defined_field_to_xml_file(field_name, field_value) ⇒ Object
add user defined field to xml file.
-
#create_space_types(model, total_bldg_floor_area, total_number_floors, standard_template, open_studio_standard) ⇒ Object
create space types.
-
#initialize(base_xml, ns) ⇒ SpatialElement
constructor
initialize SpatialElement class.
-
#prepare_final_xml_for_spatial_element ⇒ Object
write parameters to xml for spatial element.
-
#process_bldg_and_system_type(building_and_system_types, occupancy_classification, total_floor_area, total_number_floors) ⇒ Boolean
Determine the standards_building_type, bar_division_method, and system_type given: - occupancy_classification, total_floor_area, total_number_floors.
-
#read_floor_areas(parent_total_floor_area) ⇒ Object
read floor areas.
-
#set_bldg_and_system_type(occupancy_classification, total_floor_area, total_number_floors, raise_exception) ⇒ Object
set building and system type.
-
#sets_occupancy_bldg_system_types(occ_type) ⇒ Boolean
gets the standards occupancy type from the building type or the potential overwrite occupancy type.
-
#validate_positive_number_excluding_zero(name, value) ⇒ Object
validate positive number excluding zero.
-
#validate_positive_number_including_zero(name, value) ⇒ Object
validate positive number including zero.
Methods included from XmlGetSet
#get_prefix, #xget_attribute_for_element, #xget_element, #xget_id, #xget_idrefs, #xget_linked_premises, #xget_name, #xget_or_create, #xget_plurals_text_value, #xget_text, #xget_text_as_bool, #xget_text_as_date, #xget_text_as_dt, #xget_text_as_float, #xget_text_as_integer, #xset_or_create, #xset_text
Methods included from Helper
#help_calculate_hours, #help_convert, #help_count_number_of_days, #help_element_class_type_check, #help_get_attribute_value, #help_get_default_schedule_set, #help_get_duration, #help_get_end_time, #help_get_end_time_sat, #help_get_end_time_sun, #help_get_end_time_weekday, #help_get_or_create, #help_get_schedule_rule_set_from_schedule, #help_get_start_time, #help_get_start_time_sat, #help_get_start_time_sun, #help_get_start_time_weekday, #help_get_text_value, #help_get_text_value_as_bool, #help_get_text_value_as_date, #help_get_text_value_as_datetime, #help_get_text_value_as_float, #help_get_text_value_as_integer, #help_get_zone_name_list, #help_load_doc, #help_print_all_schedules, #help_print_schedule, #help_write_profile
Constructor Details
#initialize(base_xml, ns) ⇒ SpatialElement
initialize SpatialElement class
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 57 def initialize(base_xml, ns) @base_xml = base_xml @ns = ns @total_floor_area = nil @standards_building_type = nil @system_type = nil @bar_division_method = nil @space_types = {} @fraction_area = nil @space_types_floor_area = nil @conditioned_floor_area_heated_only = nil @conditioned_floor_area_cooled_only = nil @conditioned_floor_area_heated_cooled = 0 @custom_conditioned_above_grade_floor_area = nil @custom_conditioned_below_grade_floor_area = nil @user_defined_fields = REXML::Element.new("#{@ns}:UserDefinedFields") end |
Instance Attribute Details
#space_types ⇒ Object (readonly)
Returns the value of attribute space_types.
351 352 353 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 351 def space_types @space_types end |
#standards_building_type ⇒ Object (readonly)
Returns the value of attribute standards_building_type.
351 352 353 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 351 def standards_building_type @standards_building_type end |
#system_type ⇒ Object (readonly)
Returns the value of attribute system_type.
351 352 353 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 351 def system_type @system_type end |
#total_floor_area ⇒ Object (readonly)
Returns the value of attribute total_floor_area.
351 352 353 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 351 def total_floor_area @total_floor_area end |
Instance Method Details
#add_user_defined_field_to_xml_file(field_name, field_value) ⇒ Object
add user defined field to xml file
319 320 321 322 323 324 325 326 327 328 329 330 331 332 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 319 def add_user_defined_field_to_xml_file(field_name, field_value) user_defined_field = REXML::Element.new("#{@ns}:UserDefinedField") field_name_element = REXML::Element.new("#{@ns}:FieldName") field_value_element = REXML::Element.new("#{@ns}:FieldValue") if !field_value.nil? @user_defined_fields.add_element(user_defined_field) user_defined_field.add_element(field_name_element) user_defined_field.add_element(field_value_element) field_name_element.text = field_name field_value_element.text = field_value end end |
#create_space_types(model, total_bldg_floor_area, total_number_floors, standard_template, open_studio_standard) ⇒ Object
create space types
266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 266 def create_space_types(model, total_bldg_floor_area, total_number_floors, standard_template, open_studio_standard) # create space types from section type # mapping lookup_name name is needed for a few methods set_bldg_and_system_type(xget_text('OccupancyClassification'), total_bldg_floor_area, total_number_floors, false) if @standards_building_type.nil? if open_studio_standard.nil? begin open_studio_standard = Standard.build("#{standard_template}_#{@standards_building_type}") rescue StandardError => e # if the combination of standard type and bldg type fails we try the standard type alone. puts "could not find open studio standard for template #{standard_template} and bldg type: #{@standards_building_type}, trying the standard type alone" open_studio_standard = Standard.build(standard_template) raise(e) end end @space_types = get_space_types_from_building_type(@standards_building_type, standard_template, true) puts "BuildingSync.SpatialElement.create_space_types - Space types: #{@space_types} selected for building type: #{@standards_building_type} and standard template: #{standard_template}" # create space_type_map from array sum_of_ratios = 0.0 @space_types.each do |space_type_name, hash| # create space type space_type = OpenStudio::Model::SpaceType.new(model) space_type.setStandardsBuildingType(@standards_building_type) space_type.setStandardsSpaceType(space_type_name) space_type.setName("#{@standards_building_type} #{space_type_name}") # set color test = open_studio_standard.space_type_apply_rendering_color(space_type) # this uses openstudio-standards OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.SpatialElement.create_space_types', "Warning: Could not find color for #{space_type.name}") if !test # extend hash to hold new space type object hash[:space_type] = space_type # add to sum_of_ratios counter for adjustment multiplier sum_of_ratios += hash[:ratio] end # store multiplier needed to adjust sum of ratios to equal 1.0 @ratio_adjustment_multiplier = 1.0 / sum_of_ratios @space_types_floor_area = {} @space_types.each do |space_type_name, hash| ratio_of_bldg_total = hash[:ratio] * @ratio_adjustment_multiplier * @fraction_area final_floor_area = ratio_of_bldg_total * total_bldg_floor_area # I think I can just pass ratio but passing in area is cleaner @space_types_floor_area[hash[:space_type]] = { floor_area: final_floor_area } end puts 'BuildingSync.SpatialElement.create_space_types' return @space_types_floor_area end |
#prepare_final_xml_for_spatial_element ⇒ Object
write parameters to xml for spatial element
335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 335 def prepare_final_xml_for_spatial_element add_user_defined_field_to_xml_file('StandardsBuildingType', @standards_building_type) add_user_defined_field_to_xml_file('SystemType', @system_type) add_user_defined_field_to_xml_file('BarDivisionMethod', @bar_division_method) add_user_defined_field_to_xml_file('FractionArea', @fraction_area) add_user_defined_field_to_xml_file('SpaceTypesFloorArea', @space_types_floor_area) add_user_defined_field_to_xml_file('TotalFloorArea(m^2)', @total_floor_area) add_user_defined_field_to_xml_file('ConditionedFloorArea(m^2)', @conditioned_floor_area_heated_cooled) if !@conditioned_floor_area_heated_cooled.nil? add_user_defined_field_to_xml_file('HeatedFloorArea(m^2)', @conditioned_floor_area_heated_only) if !@conditioned_floor_area_heated_only.nil? add_user_defined_field_to_xml_file('CooledFloorArea(m^2)', @conditioned_floor_area_cooled_only) if !@conditioned_floor_area_cooled_only.nil? add_user_defined_field_to_xml_file('ConditionedAboveGradeFloorArea(m^2)', @custom_conditioned_above_grade_floor_area) if !@custom_conditioned_above_grade_floor_area.nil? add_user_defined_field_to_xml_file('ConditionedBelowGradeFloorArea(m^2)', @custom_conditioned_below_grade_floor_area) if !@custom_conditioned_below_grade_floor_area.nil? @base_xml.add_element(@user_defined_fields) end |
#process_bldg_and_system_type(building_and_system_types, occupancy_classification, total_floor_area, total_number_floors) ⇒ Boolean
Determine the standards_building_type, bar_division_method, and system_type given:
-
occupancy_classification, total_floor_area, total_number_floors
189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 189 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}" # 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 end end # no occ_type fit! We must give up return false end |
#read_floor_areas(parent_total_floor_area) ⇒ Object
read floor areas
79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 79 def read_floor_areas(parent_total_floor_area) @base_xml.elements.each("#{@ns}:FloorAreas/#{@ns}:FloorArea") do |floor_area_element| next if !floor_area_element.elements["#{@ns}:FloorAreaValue"] floor_area = floor_area_element.elements["#{@ns}:FloorAreaValue"].text.to_f next if floor_area.nil? floor_area_type = floor_area_element.elements["#{@ns}:FloorAreaType"].text if floor_area_type == 'Gross' @total_floor_area = OpenStudio.convert(validate_positive_number_excluding_zero('gross_floor_area', floor_area), 'ft^2', 'm^2').get elsif floor_area_type == 'Footprint' @footprint_floor_area = OpenStudio.convert(validate_positive_number_excluding_zero('@footprint_floor_area', floor_area), 'ft^2', 'm^2').get elsif floor_area_type == 'Conditioned' || floor_area_type == 'Common' || floor_area_type == 'Heated and Cooled' @conditioned_floor_area_heated_cooled += OpenStudio.convert(validate_positive_number_excluding_zero('@conditioned_floor_area_heated_cooled', floor_area), 'ft^2', 'm^2').get elsif floor_area_type == 'Heated Only' @conditioned_floor_area_heated_only = OpenStudio.convert(validate_positive_number_excluding_zero('@heated_only_floor_area', floor_area), 'ft^2', 'm^2').get elsif floor_area_type == 'Cooled Only' @conditioned_floor_area_cooled_only = OpenStudio.convert(validate_positive_number_excluding_zero('@cooled_only_floor_area', floor_area), 'ft^2', 'm^2').get elsif floor_area_type == 'Custom' if floor_area_element.elements["#{@ns}:FloorAreaCustomName"].text == 'Conditioned above grade' @custom_conditioned_above_grade_floor_area = OpenStudio.convert(validate_positive_number_excluding_zero('@custom_conditioned_above_grade_floor_area', floor_area), 'ft^2', 'm^2').get elsif floor_area_element.elements["#{@ns}:FloorAreaCustomName"].text == 'Conditioned below grade' @custom_conditioned_below_grade_floor_area = OpenStudio.convert(validate_positive_number_excluding_zero('@custom_conditioned_below_grade_floor_area', floor_area), 'ft^2', 'm^2').get end else OpenStudio.logFree(OpenStudio::Warn, 'BuildingSync.SpatialElement.generate_baseline_osm', "Unsupported floor area type found: #{floor_area_type}") end end if @total_floor_area.nil? || @total_floor_area == 0 # if the total floor area is null, we try to calculate the total area, from various conditioned areas running_floor_area = 0 if !@conditioned_floor_area_cooled_only.nil? && @conditioned_floor_area_cooled_only > 0 running_floor_area += @conditioned_floor_area_cooled_only end if !@conditioned_floor_area_heated_only.nil? && @conditioned_floor_area_heated_only > 0 running_floor_area += @conditioned_floor_area_heated_only end if !@conditioned_floor_area_heated_cooled.nil? && @conditioned_floor_area_heated_cooled > 0 running_floor_area += @conditioned_floor_area_heated_cooled end if running_floor_area > 0 @total_floor_area = running_floor_area else # if the conditions floor areas are null, we look at the conditioned above and below grade areas if !@custom_conditioned_above_grade_floor_area.nil? && @custom_conditioned_above_grade_floor_area > 0 running_floor_area += @custom_conditioned_above_grade_floor_area end if !@custom_conditioned_below_grade_floor_area.nil? && @custom_conditioned_below_grade_floor_area > 0 running_floor_area += @custom_conditioned_below_grade_floor_area end if running_floor_area > 0 @total_floor_area = running_floor_area end end end # if we did not find any area we get the parent one if @total_floor_area.nil? || @total_floor_area == 0 return parent_total_floor_area else return @total_floor_area end end |
#set_bldg_and_system_type(occupancy_classification, total_floor_area, total_number_floors, raise_exception) ⇒ Object
set building and system type
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 148 def set_bldg_and_system_type(occupancy_classification, total_floor_area, total_number_floors, raise_exception) # DOE Prototype building types:from openstudio-standards/lib/openstudio-standards/prototypes/common/prototype_metaprogramming.rb # SmallOffice, MediumOffice, LargeOffice, RetailStandalone, RetailStripmall, PrimarySchool, SecondarySchool, Outpatient # Hospital, SmallHotel, LargeHotel, QuickServiceRestaurant, FullServiceRestaurant, MidriseApartment, HighriseApartment, Warehouse if !occupancy_classification.nil? && !total_floor_area.nil? building_and_system_types = eval(File.read(BUILDING_AND_SYSTEMS_FILE_PATH)) process_bldg_and_system_type(building_and_system_types, occupancy_classification, total_floor_area, total_number_floors) if @standards_building_type == '' raise "Building type '#{occupancy_classification}' is beyond BuildingSync scope" end elsif raise_exception if occupancy_classification.nil? && !total_floor_area.nil? raise "ID: #{xget_id} occupancy classification '#{occupancy_classification}' is nil" elsif !occupancy_classification.nil? && total_floor_area.nil? raise "ID: #{xget_id} Building total floor area '#{total_floor_area}' is nil" end end end |
#sets_occupancy_bldg_system_types(occ_type) ⇒ Boolean
gets the standards occupancy type from the building type or the potential overwrite occupancy type
174 175 176 177 178 179 180 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 174 def sets_occupancy_bldg_system_types(occ_type) @standards_building_type = occ_type[:standards_building_type] @bar_division_method = occ_type[:bar_division_method] @system_type = occ_type[:system_type] OpenStudio.logFree(OpenStudio::Info, 'BuildingSync.SpatialElement.sets_occupancy_bldg_system_types', "Element ID: #{xget_id} @standards_building_type #{@standards_building_type}, @bar_division_method #{@bar_division_method} and @system_type: #{@system_type}") return true end |
#validate_positive_number_excluding_zero(name, value) ⇒ Object
validate positive number excluding zero
245 246 247 248 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 245 def validate_positive_number_excluding_zero(name, value) puts "Error: parameter #{name} must be positive and not zero." if value <= 0 return value end |
#validate_positive_number_including_zero(name, value) ⇒ Object
validate positive number including zero
254 255 256 257 |
# File 'lib/buildingsync/model_articulation/spatial_element.rb', line 254 def validate_positive_number_including_zero(name, value) puts "Error: parameter #{name} must be positive or zero." if value < 0 return value end |