From d925e4a0533ea8187f7f01980939abcb224fe7d9 Mon Sep 17 00:00:00 2001 From: Weili Xu Date: Thu, 3 Aug 2023 14:39:26 -0700 Subject: [PATCH 1/2] reorganize the elevator function and enhance the exceptional handling --- .../ashrae_90_1_prm/ashrae_90_1_prm.Model.rb | 99 +++++++++++-------- .../utilities/assertion.rb | 15 +++ 2 files changed, 75 insertions(+), 39 deletions(-) diff --git a/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb b/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb index 767729981a..2654d68c38 100644 --- a/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb +++ b/lib/openstudio-standards/standards/ashrae_90_1_prm/ashrae_90_1_prm.Model.rb @@ -779,20 +779,19 @@ def model_apply_baseline_exterior_lighting(model) # @param model [OpenStudio::Model::Model] OpenStudio model object def model_add_prm_elevators(model) # Load elevator data from userdata csv files - user_elevators = @standards_data.key?('userdata_electric_equipment') ? @standards_data['userdata_electric_equipment'] : nil - return false if user_elevators.nil? - - user_elevators.each do |user_elevator| - num_lifts = user_elevator['elevator_number_of_lifts'].to_i - next if num_lifts == 0 - - equip_name = user_elevator['name'] - number_of_levels = user_elevator['elevator_number_of_stories'].to_i - - elevator_weight_of_car = user_elevator['elevator_weight_of_car'].to_f - elevator_rated_load = user_elevator['elevator_rated_load'].to_f - elevator_speed_of_car = user_elevator['elevator_speed_of_car'].to_f - if number_of_levels < 5 + equipment_array = model.getElectricEquipments + model.getExteriorFuelEquipments + equipment_array.each do |equipment| + elevator_number_of_lifts = get_additional_property_as_integer(equipment, 'elevator_number_of_lifts', 0) + next unless elevator_number_of_lifts > 0.0 + + elevator_name = equipment.name.get + elevator_number_of_stories = get_additional_property_as_integer(equipment, 'elevator_number_of_stories', 0) + elevator_weight_of_car = get_additional_property_as_double(equipment, 'elevator_weight_of_car', 0.0) + elevator_rated_load = get_additional_property_as_double(equipment, 'elevator_rated_load', 0.0) + elevator_speed_of_car = get_additional_property_as_double(equipment, 'elevator_speed_of_car', 0.0) + elevator_counter_weight_of_car = get_additional_property_as_double(equipment, 'elevator_counter_weight_of_car', 0.0) + + if elevator_number_of_stories < 5 # From Table G3.9.2 performance rating method baseline elevator motor elevator_mech_eff = 0.58 elevator_counter_weight_of_car = 0.0 @@ -804,29 +803,23 @@ def model_add_prm_elevators(model) # From Table G3.9.2 performance rating method baseline elevator motor elevator_mech_eff = 0.64 # Determine the elevator counterweight - if user_elevator['elevator_counter_weight_of_car'].nil? + if elevator_counter_weight_of_car == 0.0 # When the proposed design counterweight is not specified # it is determined as per Table G3.9.2 elevator_counter_weight_of_car = elevator_weight_of_car + 0.4 * elevator_rated_load - else - elevator_counter_weight_of_car = user_elevator['elevator_counter_weight_of_car'].to_f end search_criteria = { 'template' => template, 'type' => 'Any' } end - - elevator_motor_bhp = (elevator_weight_of_car + elevator_rated_load - elevator_counter_weight_of_car) * elevator_speed_of_car / (33000 * elevator_mech_eff) - - # Lookup the minimum motor efficiency + elevator_motor_bhp = (elevator_weight_of_car + elevator_rated_load - elevator_counter_weight_of_car) * elevator_speed_of_car / (33000 * elevator_mech_eff) # Lookup the minimum motor efficiency elevator_motor_eff = standards_data['motors'] motor_properties = model_find_object(elevator_motor_eff, search_criteria, nil, nil, nil, nil, elevator_motor_bhp) if motor_properties.nil? - OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.elevator', "For #{equip_name}, could not find motor properties using search criteria: #{search_criteria}, motor_bhp = #{motor_bhp} hp.") + OpenStudio.logFree(OpenStudio::Error, 'prm.log', "For #{elevator_name}, could not find motor properties using search criteria: #{search_criteria}, motor_bhp = #{elevator_motor_bhp} hp.") return false end - nominal_hp = motor_properties['maximum_capacity'].to_f.round(1) # Round to nearest whole HP for niceness if nominal_hp >= 2 @@ -837,33 +830,28 @@ def model_add_prm_elevators(model) # Add 0.01 hp to avoid search errors. motor_properties = model_find_object(elevator_motor_eff, search_criteria, nil, nil, nil, nil, nominal_hp + 0.01) if motor_properties.nil? - OpenStudio.logFree(OpenStudio::Error, 'openstudio.standards.model', "For #{equip_name}, could not find nominal motor properties using search criteria: #{search_criteria}, motor_hp = #{nominal_hp} hp.") + OpenStudio.logFree(OpenStudio::Error, 'prm.log', "For #{elevator_name}, could not find nominal motor properties using search criteria: #{search_criteria}, motor_hp = #{nominal_hp} hp.") return false end motor_eff = motor_properties['nominal_full_load_efficiency'].to_f - elevator_power = num_lifts * elevator_motor_bhp * 746 / motor_eff + elevator_power = elevator_number_of_lifts * elevator_motor_bhp * 746 / motor_eff - # Set elevator power to either regular electric equipment object or - # exterior fuel equipment - if model.getElectricEquipmentByName(equip_name).is_initialized - model.getElectricEquipmentByName(equip_name).get.electricEquipmentDefinition.setDesignLevel(elevator_power) - elevator_space = model.getElectricEquipmentByName(equip_name).get.space.get - end - if model.getExteriorFuelEquipmentByName(equip_name).is_initialized - model.getExteriorFuelEquipmentByName(equip_name).exteriorFuelEquipmentDefinition.setDesignLevel(elevator_power) - elevator_space = model.getElectricEquipmentByName(equip_name).get.space.get + if equipment.is_a?(OpenStudio::Model::ElectricEquipment) + equipment.electricEquipmentDefinition.setDesignLevel(elevator_power) + else + equipment.exteriorFuelEquipmentDefinition.setDesignLevel(elevator_power) end - + elevator_space = prm_get_optional_handler(equipment, @sizing_run_dir, 'space') # Add ventilation and lighting process loads if modeled in the proposed model misc_elevator_process_loads = 0.0 - misc_elevator_process_loads += user_elevator['elevator_ventilation_cfm'].to_f * 0.33 - misc_elevator_process_loads += user_elevator['elevator_area_ft2'].to_f * 3.14 + misc_elevator_process_loads += get_additional_property_as_double(equipment, 'elevator_ventilation_cfm', 0.0) * 0.33 + misc_elevator_process_loads += get_additional_property_as_double(equipment, 'elevator_area_ft2', 0.0) * 3.14 if misc_elevator_process_loads > 0 misc_elevator_process_loads_def = OpenStudio::Model::ElectricEquipmentDefinition.new(model) - misc_elevator_process_loads_def.setName("#{equip_name} - Misc Process Loads - Def") + misc_elevator_process_loads_def.setName("#{elevator_name} - Misc Process Loads - Def") misc_elevator_process_loads_def.setDesignLevel(misc_elevator_process_loads) misc_elevator_process_loads = OpenStudio::Model::ElectricEquipment.new(misc_elevator_process_loads_def) - misc_elevator_process_loads.setName("#{equip_name} - Misc Process Loads") + misc_elevator_process_loads.setName("#{elevator_name} - Misc Process Loads") misc_elevator_process_loads.setEndUseSubcategory('Elevators') misc_elevator_process_loads.setSchedule(model.alwaysOnDiscreteSchedule) misc_elevator_process_loads.setSpace(elevator_space) @@ -1476,8 +1464,41 @@ def handle_user_input_data(model, climate_zone, sizing_run_dir, default_hvac_bui handle_zone_hvac_user_input_data(model) # load thermal zone user data from proposed model handle_thermal_zone_user_input_data(model) + # load electric equipment user data + handle_electric_equipment_user_input_data(model) end + # A function to load electric equipment csv files + # The file name is userdata_electric_equipment.csv + # @param [OpenStudio::Model::Model] model + def handle_electric_equipment_user_input_data(model) + user_data_plug_load = @standards_data.key?('userdata_electric_equipment') ? @standards_data['userdata_electric_equipment'] : nil + if user_data_plug_load && !user_data_plug_load.empty? + user_data_plug_load.each do |user_plug_load| + # Process elevator data + num_lifts = prm_read_user_data(user_plug_load, 'elevator_number_of_lifts', 0).to_i + elevator_equipment_option = model.getElectricEquipmentByName(prm_read_user_data(user_plug_load, 'name')) + if num_lifts > 0 && elevator_equipment_option.is_initialized + elevator_equipment = elevator_equipment_option.get + elevator_equipment.additionalProperties.setFeature('elevator_number_of_lifts', num_lifts) + number_of_levels = prm_read_user_data(user_plug_load, 'elevator_number_of_stories', 0).to_i + elevator_equipment.additionalProperties.setFeature('elevator_number_of_stories', number_of_levels) + elevator_weight_of_car = prm_read_user_data(user_plug_load, 'elevator_weight_of_car', 0.0).to_f + elevator_equipment.additionalProperties.setFeature('elevator_weight_of_car', elevator_weight_of_car) + elevator_weight_of_car = prm_read_user_data(user_plug_load, 'elevator_counter_weight_of_car', 0.0).to_f + elevator_equipment.additionalProperties.setFeature('elevator_counter_weight_of_car', elevator_weight_of_car) + elevator_rated_load = prm_read_user_data(user_plug_load, 'elevator_rated_load', 0.0).to_f + elevator_equipment.additionalProperties.setFeature('elevator_rated_load', elevator_rated_load) + elevator_speed_of_car = prm_read_user_data(user_plug_load, 'elevator_speed_of_car', 0.0).to_f + elevator_equipment.additionalProperties.setFeature('elevator_speed_of_car', elevator_speed_of_car) + elevator_ventilation_cfm = prm_read_user_data(user_plug_load, 'elevator_ventilation_cfm', 0.0).to_f + elevator_equipment.additionalProperties.setFeature('elevator_ventilation_cfm', elevator_ventilation_cfm) + elevator_area_ft2 = prm_read_user_data(user_plug_load, 'elevator_area_ft2', 0.0).to_f + elevator_equipment.additionalProperties.setFeature('elevator_area_ft2', elevator_area_ft2) + end + end + end + end # A function to load outdoor air data from user data csv files # The file name is userdata_design_specification_outdoor_air.csv # @param [OpenStudio::Model::Model] model diff --git a/lib/openstudio-standards/utilities/assertion.rb b/lib/openstudio-standards/utilities/assertion.rb index 0897c469f4..6e61052f2c 100644 --- a/lib/openstudio-standards/utilities/assertion.rb +++ b/lib/openstudio-standards/utilities/assertion.rb @@ -62,6 +62,21 @@ def get_additional_property_as_boolean(component, key, default = false) return value end +# PRM get an additional property from an OpenStudio object as a double, +# if no such additional property, then return default value. +# @param component [OpenStudio object] the component to get the additional property from +# @param key [String] key string +# @param default [Boolean] the default to return when there is no matching key +def get_additional_property_as_integer(component, key, default = 0.0) + value = default + if component.additionalProperties.getFeatureAsInteger(key).is_initialized + value = component.additionalProperties.getFeatureAsInteger(key).get + else + OpenStudio.logFree(OpenStudio::Warn, 'prm.log', "Cannot find the #{key} in component: #{component.name.get}, default value #{default} is used.") + end + return value +end + # PRM get an additional property from an OpenStudio object as a double, # if no such additional property, then return default value. # @param component [OpenStudio object] the component to get the additional property from From c354d005fe4d5458a5c9e881aa83a02fc810bd62 Mon Sep 17 00:00:00 2001 From: Weili Xu Date: Mon, 7 Aug 2023 09:03:50 -0700 Subject: [PATCH 2/2] update comments - address feedback --- lib/openstudio-standards/utilities/assertion.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/openstudio-standards/utilities/assertion.rb b/lib/openstudio-standards/utilities/assertion.rb index 6e61052f2c..5e9858ccb5 100644 --- a/lib/openstudio-standards/utilities/assertion.rb +++ b/lib/openstudio-standards/utilities/assertion.rb @@ -66,7 +66,7 @@ def get_additional_property_as_boolean(component, key, default = false) # if no such additional property, then return default value. # @param component [OpenStudio object] the component to get the additional property from # @param key [String] key string -# @param default [Boolean] the default to return when there is no matching key +# @param default [Integer] the default to return when there is no matching key def get_additional_property_as_integer(component, key, default = 0.0) value = default if component.additionalProperties.getFeatureAsInteger(key).is_initialized @@ -81,7 +81,7 @@ def get_additional_property_as_integer(component, key, default = 0.0) # if no such additional property, then return default value. # @param component [OpenStudio object] the component to get the additional property from # @param key [String] key string -# @param default [Boolean] the default to return when there is no matching key +# @param default [Double] the default to return when there is no matching key def get_additional_property_as_double(component, key, default = 0.0) value = default if component.additionalProperties.getFeatureAsDouble(key).is_initialized @@ -96,7 +96,7 @@ def get_additional_property_as_double(component, key, default = 0.0) # if no such additional property, then return default value. # @param component [OpenStudio object] the component to get the additional property from # @param key [String] key string -# @param default [Boolean] the default to return when there is no matching key +# @param default [String] the default to return when there is no matching key def get_additional_property_as_string(component, key, default = "") value = default if component.additionalProperties.getFeatureAsString(key).is_initialized