From bc1e205023d2983c76183a6d23874d8781964b6d Mon Sep 17 00:00:00 2001 From: Scott Horowitz Date: Tue, 17 Dec 2024 13:13:41 -0700 Subject: [PATCH 1/6] Fixes zero occupants specified for one unit in a whole MF building from being treated like zero occupants for every unit. --- Changelog.md | 1 + HPXMLtoOpenStudio/measure.rb | 14 - HPXMLtoOpenStudio/measure.xml | 26 +- HPXMLtoOpenStudio/resources/airflow.rb | 24 +- HPXMLtoOpenStudio/resources/defaults.rb | 230 +++++--- .../resources/hotwater_appliances.rb | 64 +- HPXMLtoOpenStudio/resources/internal_gains.rb | 14 +- HPXMLtoOpenStudio/resources/lighting.rb | 7 +- HPXMLtoOpenStudio/resources/misc_loads.rb | 5 + HPXMLtoOpenStudio/tests/test_airflow.rb | 20 + .../tests/test_hotwater_appliance.rb | 22 + HPXMLtoOpenStudio/tests/test_lighting.rb | 15 + HPXMLtoOpenStudio/tests/test_miscloads.rb | 63 +- workflow/hpxml_inputs.json | 4 - .../base-residents-0-runperiod-1-month.xml | 558 ------------------ 15 files changed, 378 insertions(+), 689 deletions(-) delete mode 100644 workflow/sample_files/base-residents-0-runperiod-1-month.xml diff --git a/Changelog.md b/Changelog.md index fe1aa6a5b7..b2a9029a11 100644 --- a/Changelog.md +++ b/Changelog.md @@ -3,6 +3,7 @@ __New Features__ __Bugfixes__ +- Fixes zero occupants specified for one unit in a whole MF building from being treated like zero occupants for every unit. ## OpenStudio-HPXML v1.9.1 diff --git a/HPXMLtoOpenStudio/measure.rb b/HPXMLtoOpenStudio/measure.rb index b22a139b26..0b68841d76 100644 --- a/HPXMLtoOpenStudio/measure.rb +++ b/HPXMLtoOpenStudio/measure.rb @@ -407,20 +407,6 @@ def init(model, hpxml_bldg, hpxml_header) if hpxml_header.apply_ashrae140_assumptions.nil? hpxml_header.apply_ashrae140_assumptions = false end - - if not hpxml_bldg.building_occupancy.number_of_residents.nil? - # If zero occupants, ensure end uses of interest are zeroed out - if (hpxml_bldg.building_occupancy.number_of_residents == 0) && (not hpxml_header.apply_ashrae140_assumptions) - hpxml_header.unavailable_periods.add(column_name: 'Vacancy', - begin_month: hpxml_header.sim_begin_month, - begin_day: hpxml_header.sim_begin_day, - begin_hour: 0, - end_month: hpxml_header.sim_end_month, - end_day: hpxml_header.sim_end_day, - end_hour: 24, - natvent_availability: HPXML::ScheduleUnavailable) - end - end end end diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 3869fb75a3..dfcd69c776 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - a96e00a3-319b-4f82-a104-9013094367f5 - 2024-12-09T23:44:23Z + dc3b4a16-16a9-4daa-a9ca-fc8e0bcda42c + 2024-12-17T20:11:12Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -183,13 +183,13 @@ measure.rb rb script - D7F18DFB + CA101CA3 airflow.rb rb resource - C329DF48 + 06E4A131 battery.rb @@ -327,7 +327,7 @@ defaults.rb rb resource - CCB18256 + CADAF9FE energyplus.rb @@ -351,7 +351,7 @@ hotwater_appliances.rb rb resource - 5F7B3A25 + 0B205523 hpxml.rb @@ -399,13 +399,13 @@ internal_gains.rb rb resource - 94B4EA05 + 206BE2B6 lighting.rb rb resource - 9B17C563 + 7B7F6D4C location.rb @@ -441,7 +441,7 @@ misc_loads.rb rb resource - DF088D8A + A4F201D8 model.rb @@ -651,7 +651,7 @@ test_airflow.rb rb test - DA1297B3 + 6BDC58E4 test_battery.rb @@ -681,7 +681,7 @@ test_hotwater_appliance.rb rb test - A1E1E023 + 27A0085A test_hvac.rb @@ -699,7 +699,7 @@ test_lighting.rb rb test - 9F945097 + 5300BCE3 test_location.rb @@ -711,7 +711,7 @@ test_miscloads.rb rb test - 974B3838 + 784CC382 test_pv.rb diff --git a/HPXMLtoOpenStudio/resources/airflow.rb b/HPXMLtoOpenStudio/resources/airflow.rb index 99985b4f77..8709970c39 100644 --- a/HPXMLtoOpenStudio/resources/airflow.rb +++ b/HPXMLtoOpenStudio/resources/airflow.rb @@ -38,6 +38,10 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul elsif f.used_for_seasonal_cooling_load_reduction vent_fans[:whf] << f elsif f.used_for_local_ventilation + if hpxml_bldg.building_occupancy.number_of_residents == 0 + # Operational calculation w/ zero occupants, zero out energy use + continue + end if f.fan_location == HPXML::LocationKitchen vent_fans[:kitchen] << f elsif f.fan_location == HPXML::LocationBath @@ -588,12 +592,19 @@ def self.apply_natural_ventilation_and_whole_house_fan(runner, model, spaces, hp vent_program.addLine(' Set Qwhf = WHF_Flow*Adj') vent_program.addLine(" Set #{cond_to_zone_flow_rate_actuator.name} = WHF_Flow*Adj") unless whf_zone.nil? vent_program.addLine(' Set WHF_W = 0') - vent_fans[:whf].each do |vent_whf| - vent_program.addLine(" Set WHF_W = WHF_W + #{vent_whf.fan_power} * #{whf_avail_sensors[vent_whf.id].name}") + if hpxml_bldg.building_occupancy.number_of_residents != 0 # If operational calculation w/ zero occupants, zero out whole house fan + vent_fans[:whf].each do |vent_whf| + vent_program.addLine(" Set WHF_W = WHF_W + #{vent_whf.fan_power} * #{whf_avail_sensors[vent_whf.id].name}") + end end vent_program.addLine(" Set #{whf_elec_actuator.name} = WHF_W*Adj") vent_program.addLine(' ElseIf (NVavail > 0)') # Natural ventilation - vent_program.addLine(" Set NVArea = #{UnitConversions.convert(area, 'ft^2', 'cm^2')}") + if hpxml_bldg.building_occupancy.number_of_residents == 0 + # Operational calculation w/ zero occupants, zero out natural ventilation + vent_program.addLine(' Set NVArea = 0') + else + vent_program.addLine(" Set NVArea = #{UnitConversions.convert(area, 'ft^2', 'cm^2')}") + end vent_program.addLine(" Set Cs = #{UnitConversions.convert(c_s, 'ft^2/(s^2*R)', 'L^2/(s^2*cm^4*K)')}") vent_program.addLine(" Set Cw = #{c_w * 0.01}") vent_program.addLine(' Set Tdiff = Tin-Tout') @@ -2298,6 +2309,7 @@ def self.apply_infiltration_adjustment_to_conditioned(runner, model, spaces, hpx clothes_dryer_in_cond_space = hpxml_bldg.clothes_dryers.empty? ? true : HPXML::conditioned_locations_this_unit.include?(hpxml_bldg.clothes_dryers[0].location) vented_dryers = hpxml_bldg.clothes_dryers.select { |cd| cd.is_vented && cd.vented_flow_rate.to_f > 0 } vented_dryers.each_with_index do |vented_dryer, index| + next if hpxml_bldg.building_occupancy.number_of_residents == 0 # Operational calculation w/ zero occupants, zero out energy use next unless clothes_dryer_in_cond_space # Infiltration impact @@ -2915,11 +2927,11 @@ def self.get_mech_vent_qtot_cfm(nbeds, cfa) # @param is_balanced [TODO] TODO # @param frac_imbal [TODO] TODO # @param a_ext [TODO] TODO - # @param bldg_type [TODO] TODO + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param hours_in_operation [TODO] TODO # @return [TODO] TODO - def self.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, a_ext, bldg_type, eri_version, hours_in_operation) + def self.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, a_ext, unit_type, eri_version, hours_in_operation) q_inf_eff = q_inf * a_ext if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2022') if frac_imbal == 0 @@ -2940,7 +2952,7 @@ def self.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, a_ext, bl end q_fan = q_tot - phi * q_inf_eff else - if [HPXML::ResidentialTypeApartment, HPXML::ResidentialTypeSFA].include? bldg_type + if [HPXML::ResidentialTypeApartment, HPXML::ResidentialTypeSFA].include? unit_type # No infiltration credit for attached/multifamily return q_tot end diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb index 55f0778b2b..841bc497d1 100644 --- a/HPXMLtoOpenStudio/resources/defaults.rb +++ b/HPXMLtoOpenStudio/resources/defaults.rb @@ -829,13 +829,6 @@ def self.apply_neighbor_buildings(hpxml_bldg) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_building_occupancy(hpxml_bldg, schedules_file) - if not hpxml_bldg.building_occupancy.number_of_residents.nil? - # Set equivalent number of bedrooms for operational calculation; this is an adjustment on - # ANSI/RESNET/ICC 301 or Building America equations, which are based on number of bedrooms. - hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms = get_equivalent_nbeds_for_operational_calculation(hpxml_bldg) - else - hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms = hpxml_bldg.building_construction.number_of_bedrooms - end schedules_file_includes_occupants = (schedules_file.nil? ? false : schedules_file.includes_col_name(SchedulesFile::Columns[:Occupants].name)) if hpxml_bldg.building_occupancy.weekday_fractions.nil? && !schedules_file_includes_occupants hpxml_bldg.building_occupancy.weekday_fractions = @default_schedules_csv_data[SchedulesFile::Columns[:Occupants].name]['WeekdayScheduleFractions'] @@ -3689,7 +3682,9 @@ def self.apply_ceiling_fans(hpxml_bldg, weather, schedules_file) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms + nbeds = hpxml_bldg.building_construction.number_of_bedrooms + n_occ = hpxml_bldg.building_occupancy.number_of_residents + unit_type = hpxml_bldg.building_construction.residential_facility_type cfa = hpxml_bldg.building_construction.conditioned_floor_area hpxml_bldg.pools.each do |pool| next if pool.type == HPXML::TypeNone @@ -3697,7 +3692,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) if pool.pump_type != HPXML::TypeNone # Pump if pool.pump_kwh_per_year.nil? - pool.pump_kwh_per_year = get_pool_pump_annual_energy(cfa, nbeds_eq) + pool.pump_kwh_per_year = get_pool_pump_annual_energy(cfa, nbeds, n_occ, unit_type) pool.pump_kwh_per_year_isdefaulted = true end if pool.pump_usage_multiplier.nil? @@ -3723,7 +3718,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) # Heater if pool.heater_load_value.nil? - default_heater_load_units, default_heater_load_value = get_pool_heater_annual_energy(cfa, nbeds_eq, pool.heater_type) + default_heater_load_units, default_heater_load_value = get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, pool.heater_type) pool.heater_load_units = default_heater_load_units pool.heater_load_value = default_heater_load_value pool.heater_load_value_isdefaulted = true @@ -3753,7 +3748,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) if spa.pump_type != HPXML::TypeNone # Pump if spa.pump_kwh_per_year.nil? - spa.pump_kwh_per_year = get_permanent_spa_pump_annual_energy(cfa, nbeds_eq) + spa.pump_kwh_per_year = get_permanent_spa_pump_annual_energy(cfa, nbeds, n_occ, unit_type) spa.pump_kwh_per_year_isdefaulted = true end if spa.pump_usage_multiplier.nil? @@ -3779,7 +3774,7 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) # Heater if spa.heater_load_value.nil? - default_heater_load_units, default_heater_load_value = get_permanent_spa_heater_annual_energy(cfa, nbeds_eq, spa.heater_type) + default_heater_load_units, default_heater_load_value = get_permanent_spa_heater_annual_energy(cfa, nbeds, n_occ, unit_type, spa.heater_type) spa.heater_load_units = default_heater_load_units spa.heater_load_value = default_heater_load_value spa.heater_load_value_isdefaulted = true @@ -3812,13 +3807,12 @@ def self.apply_pools_and_permanent_spas(hpxml_bldg, schedules_file) def self.apply_plug_loads(hpxml_bldg, schedules_file) cfa = hpxml_bldg.building_construction.conditioned_floor_area nbeds = hpxml_bldg.building_construction.number_of_bedrooms - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms - num_occ = hpxml_bldg.building_occupancy.number_of_residents + n_occ = hpxml_bldg.building_occupancy.number_of_residents unit_type = hpxml_bldg.building_construction.residential_facility_type hpxml_bldg.plug_loads.each do |plug_load| case plug_load.plug_load_type when HPXML::PlugLoadTypeOther - default_annual_kwh, default_sens_frac, default_lat_frac = get_residual_mels_values(cfa, num_occ, unit_type) + default_annual_kwh, default_sens_frac, default_lat_frac = get_residual_mels_values(cfa, n_occ, unit_type) if plug_load.kwh_per_year.nil? plug_load.kwh_per_year = default_annual_kwh plug_load.kwh_per_year_isdefaulted = true @@ -3845,7 +3839,7 @@ def self.apply_plug_loads(hpxml_bldg, schedules_file) plug_load.monthly_multipliers_isdefaulted = true end when HPXML::PlugLoadTypeTelevision - default_annual_kwh, default_sens_frac, default_lat_frac = get_televisions_values(cfa, nbeds, num_occ, unit_type) + default_annual_kwh, default_sens_frac, default_lat_frac = get_televisions_values(cfa, nbeds, n_occ, unit_type) if plug_load.kwh_per_year.nil? plug_load.kwh_per_year = default_annual_kwh plug_load.kwh_per_year_isdefaulted = true @@ -3899,7 +3893,7 @@ def self.apply_plug_loads(hpxml_bldg, schedules_file) plug_load.monthly_multipliers_isdefaulted = true end when HPXML::PlugLoadTypeWellPump - default_annual_kwh = get_detault_well_pump_annual_energy(cfa, nbeds_eq) + default_annual_kwh = get_detault_well_pump_annual_energy(cfa, nbeds, n_occ, unit_type) if plug_load.kwh_per_year.nil? plug_load.kwh_per_year = default_annual_kwh plug_load.kwh_per_year_isdefaulted = true @@ -3940,12 +3934,14 @@ def self.apply_plug_loads(hpxml_bldg, schedules_file) # @return [nil] def self.apply_fuel_loads(hpxml_bldg, schedules_file) cfa = hpxml_bldg.building_construction.conditioned_floor_area - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms + nbeds = hpxml_bldg.building_construction.number_of_bedrooms + n_occ = hpxml_bldg.building_occupancy.number_of_residents + unit_type = hpxml_bldg.building_construction.residential_facility_type hpxml_bldg.fuel_loads.each do |fuel_load| case fuel_load.fuel_load_type when HPXML::FuelLoadTypeGrill if fuel_load.therm_per_year.nil? - fuel_load.therm_per_year = get_gas_grill_annual_energy(cfa, nbeds_eq) + fuel_load.therm_per_year = get_gas_grill_annual_energy(cfa, nbeds, n_occ, unit_type) fuel_load.therm_per_year_isdefaulted = true end if fuel_load.frac_sensible.nil? @@ -3971,7 +3967,7 @@ def self.apply_fuel_loads(hpxml_bldg, schedules_file) end when HPXML::FuelLoadTypeLighting if fuel_load.therm_per_year.nil? - fuel_load.therm_per_year = get_detault_gas_lighting_annual_energy(cfa, nbeds_eq) + fuel_load.therm_per_year = get_detault_gas_lighting_annual_energy(cfa, nbeds, n_occ, unit_type) fuel_load.therm_per_year_isdefaulted = true end if fuel_load.frac_sensible.nil? @@ -3997,7 +3993,7 @@ def self.apply_fuel_loads(hpxml_bldg, schedules_file) end when HPXML::FuelLoadTypeFireplace if fuel_load.therm_per_year.nil? - fuel_load.therm_per_year = get_gas_fireplace_annual_energy(cfa, nbeds_eq) + fuel_load.therm_per_year = get_gas_fireplace_annual_energy(cfa, nbeds, n_occ, unit_type) fuel_load.therm_per_year_isdefaulted = true end if fuel_load.frac_sensible.nil? @@ -4109,26 +4105,33 @@ def self.get_orientation_from_azimuth(azimuth) # Gets the equivalent number of bedrooms for an operational calculation (i.e., when number # of occupants are provided in the HPXML); this is an adjustment to the ANSI/RESNET/ICC 301 or Building - # America equations, which are based on number of bedrooms. + # America equations, which are based on number of bedrooms. If an asset calculation (number + # of occupants provided), the number of bedrooms is simply returned. # # This is used to adjust occupancy-driven end uses from asset calculations (based on number # of bedrooms) to operational calculations (based on number of occupants). # - # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit + # Source: 2020 RECS weighted regressions between NBEDS and NHSHLDMEM (sample weights = NWEIGHT) + # + # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Equivalent number of bedrooms - def self.get_equivalent_nbeds_for_operational_calculation(hpxml_bldg) - n_occs = hpxml_bldg.building_occupancy.number_of_residents - unit_type = hpxml_bldg.building_construction.residential_facility_type - # Relations below come from 2020 RECS weighted regressions between NBEDS and NHSHLDMEM (sample weights = NWEIGHT) + def self.get_equivalent_nbeds(nbeds, n_occ, unit_type) + if n_occ.nil? + # No occupants specified, asset rating + return nbeds + end + case unit_type when HPXML::ResidentialTypeApartment - return -1.36 + 1.49 * n_occs + return -1.36 + 1.49 * n_occ when HPXML::ResidentialTypeSFA - return -1.98 + 1.89 * n_occs + return -1.98 + 1.89 * n_occ when HPXML::ResidentialTypeSFD - return -2.19 + 2.08 * n_occs + return -2.19 + 2.08 * n_occ when HPXML::ResidentialTypeManufactured - return -1.26 + 1.61 * n_occs + return -1.26 + 1.61 * n_occ else fail "Unexpected residential facility type: #{unit_type}." end @@ -4719,7 +4722,7 @@ def self.get_mech_vent_flow_rate_for_vent_fan(hpxml_bldg, vent_fan, weather, eri cfa = hpxml_bldg.building_construction.conditioned_floor_area nbeds = hpxml_bldg.building_construction.number_of_bedrooms infil_values = Airflow.get_values_from_air_infiltration_measurements(hpxml_bldg, weather) - bldg_type = hpxml_bldg.building_construction.residential_facility_type + unit_type = hpxml_bldg.building_construction.residential_facility_type nl = Airflow.get_infiltration_NL_from_SLA(infil_values[:sla], infil_values[:height]) q_inf = Airflow.get_infiltration_Qinf_from_NL(nl, weather, cfa) @@ -4729,7 +4732,7 @@ def self.get_mech_vent_flow_rate_for_vent_fan(hpxml_bldg, vent_fan, weather, eri else is_balanced, frac_imbal = false, 1.0 end - q_fan = Airflow.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, infil_values[:a_ext], bldg_type, eri_version, vent_fan.hours_in_operation) + q_fan = Airflow.get_mech_vent_qfan_cfm(q_tot, q_inf, is_balanced, frac_imbal, infil_values[:a_ext], unit_type, eri_version, vent_fan.hours_in_operation) return q_fan end @@ -5665,21 +5668,21 @@ def self.get_occupancy_values() # and sensible/latent fractions. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) - # @param num_occ [Double] Number of occupants in the dwelling unit - # @param unit_type [String] HPXML::ResidentialTypeXXX type of dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Array] Plug loads annual use (kWh), sensible/latent fractions - def self.get_residual_mels_values(cfa, num_occ = nil, unit_type = nil) - if num_occ.nil? # Asset calculation + def self.get_residual_mels_values(cfa, n_occ = nil, unit_type = nil) + if n_occ.nil? # Asset calculation # ANSI/RESNET/ICC 301 annual_kwh = 0.91 * cfa else # Operational calculation # RECS 2020 if unit_type == HPXML::ResidentialTypeSFD - annual_kwh = 786.9 + 241.8 * num_occ + 0.33 * cfa + annual_kwh = 786.9 + 241.8 * n_occ + 0.33 * cfa elsif unit_type == HPXML::ResidentialTypeSFA - annual_kwh = 654.9 + 206.5 * num_occ + 0.21 * cfa + annual_kwh = 654.9 + 206.5 * n_occ + 0.21 * cfa elsif unit_type == HPXML::ResidentialTypeApartment - annual_kwh = 706.6 + 149.3 * num_occ + 0.10 * cfa + annual_kwh = 706.6 + 149.3 * n_occ + 0.10 * cfa elsif unit_type == HPXML::ResidentialTypeManufactured annual_kwh = 1795.1 # No good relationship found in RECS, so just using a constant value end @@ -5694,11 +5697,11 @@ def self.get_residual_mels_values(cfa, num_occ = nil, unit_type = nil) # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit - # @param num_occ [Double] Number of occupants in the dwelling unit - # @param unit_type [String] HPXML::ResidentialTypeXXX type of dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Array] Television annual use (kWh), sensible/latent fractions - def self.get_televisions_values(cfa, nbeds, num_occ = nil, unit_type = nil) - if num_occ.nil? # Asset calculation + def self.get_televisions_values(cfa, nbeds, n_occ = nil, unit_type = nil) + if n_occ.nil? # Asset calculation # ANSI/RESNET/ICC 301 annual_kwh = 413.0 + 69.0 * nbeds else # Operational calculation @@ -5710,13 +5713,13 @@ def self.get_televisions_values(cfa, nbeds, num_occ = nil, unit_type = nil) # - MH: 12.6 + 287.5 * num_tv case unit_type when HPXML::ResidentialTypeSFD - annual_kwh = 334.0 + 92.2 * num_occ + 0.06 * cfa + annual_kwh = 334.0 + 92.2 * n_occ + 0.06 * cfa when HPXML::ResidentialTypeSFA - annual_kwh = 283.9 + 80.1 * num_occ + 0.07 * cfa + annual_kwh = 283.9 + 80.1 * n_occ + 0.07 * cfa when HPXML::ResidentialTypeApartment - annual_kwh = 190.3 + 81.0 * num_occ + 0.11 * cfa + annual_kwh = 190.3 + 81.0 * n_occ + 0.11 * cfa when HPXML::ResidentialTypeManufactured - annual_kwh = 99.9 + 129.6 * num_occ + 0.21 * cfa + annual_kwh = 99.9 + 129.6 * n_occ + 0.21 * cfa end end frac_lost = 0.0 @@ -5729,29 +5732,52 @@ def self.get_televisions_values(cfa, nbeds, num_occ = nil, unit_type = nil) # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (kWh/yr) - def self.get_pool_pump_annual_energy(cfa, nbeds) - return 158.6 / 0.070 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_pool_pump_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 158.6 / 0.070 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default pool heater annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param type [String] Type of heater (HPXML::HeaterTypeXXX) # @return [Array] Energy units (HPXML::UnitsXXX), annual energy use (kWh/yr or therm/yr) - def self.get_pool_heater_annual_energy(cfa, nbeds, type) + def self.get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type) + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + load_units = nil load_value = nil if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include? type load_units = HPXML::UnitsKwhPerYear - load_value = 8.3 / 0.004 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return load_type, 0.0 + end + + load_value = 8.3 / 0.004 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr if type == HPXML::HeaterTypeHeatPump load_value /= 5.0 # Assume seasonal COP of 5.0 per https://www.energy.gov/energysaver/heat-pump-swimming-pool-heaters end elsif type == HPXML::HeaterTypeGas load_units = HPXML::UnitsThermPerYear - load_value = 3.0 / 0.014 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # therm/yr + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return load_type, 0.0 + end + + load_value = 3.0 / 0.014 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # therm/yr end return load_units, load_value end @@ -5760,29 +5786,52 @@ def self.get_pool_heater_annual_energy(cfa, nbeds, type) # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (kWh/yr) - def self.get_permanent_spa_pump_annual_energy(cfa, nbeds) - return 59.5 / 0.059 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr + def self.get_permanent_spa_pump_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 59.5 / 0.059 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr end # Gets the default permanent spa heater annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param type [String] Type of heater (HPXML::HeaterTypeXXX) # @return [Array] Energy units (HPXML::UnitsXXX), annual energy use (kWh/yr or therm/yr) - def self.get_permanent_spa_heater_annual_energy(cfa, nbeds, type) + def self.get_permanent_spa_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type) + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + load_units = nil load_value = nil if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include? type load_units = HPXML::UnitsKwhPerYear - load_value = 49.0 / 0.048 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return load_type, 0.0 + end + + load_value = 49.0 / 0.048 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr if type == HPXML::HeaterTypeHeatPump load_value /= 5.0 # Assume seasonal COP of 5.0 per https://www.energy.gov/energysaver/heat-pump-swimming-pool-heaters end elsif type == HPXML::HeaterTypeGas load_units = HPXML::UnitsThermPerYear - load_value = 0.87 / 0.011 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) # therm/yr + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return load_type, 0.0 + end + + load_value = 0.87 / 0.011 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # therm/yr end return load_units, load_value end @@ -5802,44 +5851,89 @@ def self.get_electric_vehicle_charging_annual_energy() # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (kWh/yr) - def self.get_detault_well_pump_annual_energy(cfa, nbeds) - return 50.8 / 0.127 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_detault_well_pump_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 50.8 / 0.127 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default gas grill annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (therm/yr) - def self.get_gas_grill_annual_energy(cfa, nbeds) - return 0.87 / 0.029 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_gas_grill_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 0.87 / 0.029 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default gas lighting annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (therm/yr) - def self.get_detault_gas_lighting_annual_energy(cfa, nbeds) - return 0.22 / 0.012 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_detault_gas_lighting_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 0.22 / 0.012 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default gas fireplace annual energy use. # # @param cfa [Double] Conditioned floor area in the dwelling unit (ft2) # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (therm/yr) - def self.get_gas_fireplace_annual_energy(cfa, nbeds) - return 1.95 / 0.032 * (0.5 + 0.25 * nbeds / 3.0 + 0.25 * cfa / 1920.0) + def self.get_gas_fireplace_annual_energy(cfa, nbeds, n_occ, unit_type) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + + return 1.95 / 0.032 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) end # Gets the default values associated with general water use internal gains. # - # @param nbeds_eq [Integer] Number of bedrooms (or equivalent bedrooms, as adjusted by the number of occupants) in the dwelling unit + # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param general_water_use_usage_multiplier [Double] Usage multiplier on internal gains # @return [Array] Sensible/latent internal gains (Btu/yr) - def self.get_water_use_internal_gains(nbeds_eq, general_water_use_usage_multiplier = 1.0) + def self.get_water_use_internal_gains(nbeds, n_occ, unit_type, general_water_use_usage_multiplier = 1.0) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out internal gains + return 0.0, 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + # ANSI/RESNET/ICC 301 - Table 4.2.2(3). Internal Gains for Reference Homes sens_gains = (-1227.0 - 409.0 * nbeds_eq) * general_water_use_usage_multiplier # Btu/day lat_gains = (1245.0 + 415.0 * nbeds_eq) * general_water_use_usage_multiplier # Btu/day diff --git a/HPXMLtoOpenStudio/resources/hotwater_appliances.rb b/HPXMLtoOpenStudio/resources/hotwater_appliances.rb index 1b5aa56894..36dbfcb758 100644 --- a/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +++ b/HPXMLtoOpenStudio/resources/hotwater_appliances.rb @@ -21,8 +21,8 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul fixtures_usage_multiplier = hpxml_bldg.water_heating.water_fixtures_usage_multiplier conditioned_space = spaces[HPXML::LocationConditionedSpace] nbeds = hpxml_bldg.building_construction.number_of_bedrooms - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms n_occ = hpxml_bldg.building_occupancy.number_of_residents + unit_type = hpxml_bldg.building_construction.residential_facility_type eri_version = hpxml_header.eri_calculation_version unit_multiplier = hpxml_bldg.building_construction.number_of_units @@ -56,7 +56,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Clothes washer energy if not clothes_washer.nil? cw_space = Geometry.get_space_from_location(clothes_washer.location, spaces) - cw_annual_kwh, cw_frac_sens, cw_frac_lat, cw_gpd = calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, clothes_washer, cw_space.nil?, n_occ) + cw_annual_kwh, cw_frac_sens, cw_frac_lat, cw_gpd = calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, n_occ, clothes_washer, cw_space.nil?) # Create schedule cw_power_schedule = nil @@ -98,7 +98,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Clothes dryer energy if not clothes_dryer.nil? cd_space = Geometry.get_space_from_location(clothes_dryer.location, spaces) - cd_annual_kwh, cd_annual_therm, cd_frac_sens, cd_frac_lat = calc_clothes_dryer_energy(runner, eri_version, nbeds, clothes_dryer, clothes_washer, cd_space.nil?, n_occ) + cd_annual_kwh, cd_annual_therm, cd_frac_sens, cd_frac_lat = calc_clothes_dryer_energy(runner, eri_version, nbeds, n_occ, clothes_dryer, clothes_washer, cd_space.nil?) # Create schedule cd_schedule = nil @@ -154,7 +154,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Dishwasher energy if not dishwasher.nil? dw_space = Geometry.get_space_from_location(dishwasher.location, spaces) - dw_annual_kwh, dw_frac_sens, dw_frac_lat, dw_gpd = calc_dishwasher_energy_gpd(runner, eri_version, nbeds, dishwasher, dw_space.nil?, n_occ) + dw_annual_kwh, dw_frac_sens, dw_frac_lat, dw_gpd = calc_dishwasher_energy_gpd(runner, eri_version, nbeds, n_occ, dishwasher, dw_space.nil?) # Create schedule dw_power_schedule = nil @@ -300,7 +300,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Cooking Range energy if not cooking_range.nil? cook_space = Geometry.get_space_from_location(cooking_range.location, spaces) - cook_annual_kwh, cook_annual_therm, cook_frac_sens, cook_frac_lat = calc_range_oven_energy(runner, nbeds_eq, cooking_range, oven, cook_space.nil?) + cook_annual_kwh, cook_annual_therm, cook_frac_sens, cook_frac_lat = calc_range_oven_energy(runner, nbeds, n_occ, unit_type, cooking_range, oven, cook_space.nil?) # Create schedule cook_schedule = nil @@ -390,7 +390,7 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul wh_setpoint = Defaults.get_water_heater_temperature(eri_version) if wh_setpoint.nil? # using detailed schedules avg_setpoint_temp += wh_setpoint * water_heating_system.fraction_dhw_load_served end - daily_wh_inlet_temperatures = calc_water_heater_daily_inlet_temperatures(weather, nbeds_eq, hot_water_distribution, frac_low_flow_fixtures) + daily_wh_inlet_temperatures = calc_water_heater_daily_inlet_temperatures(weather, nbeds, n_occ, unit_type, hot_water_distribution, frac_low_flow_fixtures) daily_wh_inlet_temperatures_c = daily_wh_inlet_temperatures.map { |t| UnitConversions.convert(t, 'F', 'C') } daily_mw_fractions = calc_mixed_water_daily_fractions(daily_wh_inlet_temperatures, avg_setpoint_temp, t_mix) @@ -589,12 +589,21 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul # Calculates cooking range/oven annual energy use. # # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings - # @param nbeds_eq [Integer] Number of bedrooms (or equivalent bedrooms, as adjusted by the number of occupants) in the dwelling unit + # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param cooking_range [HPXML::CookingRange] The HPXML cooking range of interest # @param oven [HPXML::Oven] The HPXML oven of interest # @param is_outside [Boolean] Whether the appliance is located outside the dwelling unit # @return [Array] Annual electricity use (kWh), annual fuel use (therm), sensible/latent fractions - def self.calc_range_oven_energy(runner, nbeds_eq, cooking_range, oven, is_outside = false) + def self.calc_range_oven_energy(runner, nbeds, n_occ, unit_type, cooking_range, oven, is_outside = false) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0, 0.0, 0.0, 0.0 + end + + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + if cooking_range.is_induction burner_ef = 0.91 else @@ -644,11 +653,16 @@ def self.calc_range_oven_energy(runner, nbeds_eq, cooking_range, oven, is_outsid # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit # @param dishwasher [HPXML::Dishwasher] The HPXML dishwasher of interest # @param is_outside [Boolean] Whether the appliance is located outside the dwelling unit - # @param n_occ [Double] Number of occupants in the dwelling unit # @return [Array] Annual electricity use (kWh), sensible/latent fractions, hot water use (gal/day) - def self.calc_dishwasher_energy_gpd(runner, eri_version, nbeds, dishwasher, is_outside = false, n_occ = nil) + def self.calc_dishwasher_energy_gpd(runner, eri_version, nbeds, n_occ, dishwasher, is_outside = false) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0, 0.0, 0.0, 0.0 + end + if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2019A') if dishwasher.rated_annual_kwh.nil? dishwasher.rated_annual_kwh = calc_dishwasher_annual_kwh_from_ef(dishwasher.energy_factor) @@ -725,12 +739,17 @@ def self.calc_dishwasher_annual_kwh_from_ef(ef) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit # @param clothes_dryer [HPXML::ClothesDryer] The HPXML clothes dryer of interest # @param clothes_washer [HPXML::ClothesWasher] The related HPXML clothes washer, which affects dryer use # @param is_outside [Boolean] Whether the appliance is located outside the dwelling unit - # @param n_occ [Double] Number of occupants in the dwelling unit # @return [Array] Annual electricity use (kWh), annual fuel use (therm), sensible/latent fractions - def self.calc_clothes_dryer_energy(runner, eri_version, nbeds, clothes_dryer, clothes_washer, is_outside = false, n_occ = nil) + def self.calc_clothes_dryer_energy(runner, eri_version, nbeds, n_occ, clothes_dryer, clothes_washer, is_outside = false) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0, 0.0, 0.0, 0.0 + end + if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2019A') if clothes_dryer.combined_energy_factor.nil? clothes_dryer.combined_energy_factor = calc_clothes_dryer_cef_from_ef(clothes_dryer.energy_factor) @@ -827,11 +846,16 @@ def self.calc_clothes_dryer_ef_from_cef(cef) # @param runner [OpenStudio::Measure::OSRunner] Object typically used to display warnings # @param eri_version [String] Version of the ANSI/RESNET/ICC 301 Standard to use for equations/assumptions # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit # @param clothes_washer [HPXML::ClothesWasher] The HPXML clothes washer of interest # @param is_outside [Boolean] Whether the appliance is located outside the dwelling unit - # @param n_occ [Double] Number of occupants in the dwelling unit # @return [Array] Annual electricity use (kWh), sensible/latent fractions, hot water use (gal/day) - def self.calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, clothes_washer, is_outside = false, n_occ = nil) + def self.calc_clothes_washer_energy_gpd(runner, eri_version, nbeds, n_occ, clothes_washer, is_outside = false) + if n_occ == 0 + # Operational calculation w/ zero occupants, zero out energy use + return 0.0, 0.0, 0.0, 0.0 + end + if Constants::ERIVersions.index(eri_version) >= Constants::ERIVersions.index('2019A') gas_h20 = 0.3914 # (gal/cyc) per (therm/y) elec_h20 = 0.0178 # (gal/cyc) per (kWh/y) @@ -1056,11 +1080,19 @@ def self.get_dwhr_factors(nbeds_eq, hot_water_distribution, frac_low_flow_fixtur # there is a drain water heat recovery device. # # @param weather [WeatherFile] Weather object containing EPW information - # @param nbeds_eq [Integer] Number of bedrooms (or equivalent bedrooms, as adjusted by the number of occupants) in the dwelling unit + # @param nbeds [Integer] Number of bedrooms in the dwelling unit + # @param n_occ [Double] Number of occupants in the dwelling unit + # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @param hot_water_distribution [HPXML::HotWaterDistribution] The HPXML hot water distribution system of interest # @param frac_low_flow_fixtures [Double] The fraction of fixtures considered low-flow # @return [Array] Daily water heater inlet temperatures (F) - def self.calc_water_heater_daily_inlet_temperatures(weather, nbeds_eq, hot_water_distribution, frac_low_flow_fixtures) + def self.calc_water_heater_daily_inlet_temperatures(weather, nbeds, n_occ, unit_type, hot_water_distribution, frac_low_flow_fixtures) + if n_occ == 0 + # Operational calculation w/ zero occupants + nbeds_eq = 0 + else + nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) + end wh_temps_daily = weather.data.MainsDailyTemps.dup if (not hot_water_distribution.dwhr_efficiency.nil?) # Per ANSI/RESNET/ICC 301 diff --git a/HPXMLtoOpenStudio/resources/internal_gains.rb b/HPXMLtoOpenStudio/resources/internal_gains.rb index 3480915acd..281f2c0b81 100644 --- a/HPXMLtoOpenStudio/resources/internal_gains.rb +++ b/HPXMLtoOpenStudio/resources/internal_gains.rb @@ -13,11 +13,11 @@ module InternalGains # @return [nil] def self.apply_building_occupants(runner, model, hpxml_bldg, hpxml_header, spaces, schedules_file) if hpxml_bldg.building_occupancy.number_of_residents.nil? # Asset calculation - num_occ = Geometry.get_occupancy_default_num(nbeds: hpxml_bldg.building_construction.number_of_bedrooms) + n_occ = Geometry.get_occupancy_default_num(nbeds: hpxml_bldg.building_construction.number_of_bedrooms) else # Operational calculation - num_occ = hpxml_bldg.building_occupancy.number_of_residents + n_occ = hpxml_bldg.building_occupancy.number_of_residents end - return if num_occ <= 0 + return if n_occ <= 0 occ_gain, _hrs_per_day, sens_frac, _lat_frac = Defaults.get_occupancy_values() activity_per_person = UnitConversions.convert(occ_gain, 'Btu/hr', 'W') @@ -60,7 +60,7 @@ def self.apply_building_occupants(runner, model, hpxml_bldg, hpxml_header, space occ.setName(Constants::ObjectTypeOccupants) occ.setSpace(spaces[HPXML::LocationConditionedSpace]) occ_def.setName(Constants::ObjectTypeOccupants) - occ_def.setNumberofPeople(num_occ) + occ_def.setNumberofPeople(n_occ) occ_def.setFractionRadiant(occ_rad) occ_def.setSensibleHeatFraction(occ_sens) occ_def.setMeanRadiantTemperatureCalculationType('ZoneAveraged') @@ -81,11 +81,13 @@ def self.apply_building_occupants(runner, model, hpxml_bldg, hpxml_header, space # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_general_water_use(runner, model, hpxml_bldg, hpxml_header, spaces, schedules_file) + nbeds = hpxml_bldg.building_construction.number_of_bedrooms + n_occ = hpxml_bldg.building_occupancy.number_of_residents + unit_type = hpxml_bldg.building_construction.residential_facility_type general_water_use_usage_multiplier = hpxml_bldg.building_occupancy.general_water_use_usage_multiplier - nbeds_eq = hpxml_bldg.building_construction.additional_properties.equivalent_number_of_bedrooms if not hpxml_header.apply_ashrae140_assumptions - water_sens_btu, water_lat_btu = Defaults.get_water_use_internal_gains(nbeds_eq, general_water_use_usage_multiplier) + water_sens_btu, water_lat_btu = Defaults.get_water_use_internal_gains(nbeds, n_occ, unit_type, general_water_use_usage_multiplier) # Create schedule water_schedule = nil diff --git a/HPXMLtoOpenStudio/resources/lighting.rb b/HPXMLtoOpenStudio/resources/lighting.rb index 53a0dfec1f..551f48acf4 100644 --- a/HPXMLtoOpenStudio/resources/lighting.rb +++ b/HPXMLtoOpenStudio/resources/lighting.rb @@ -17,6 +17,7 @@ def self.apply(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) unit_multiplier = hpxml_bldg.building_construction.number_of_units cfa = hpxml_bldg.building_construction.conditioned_floor_area eri_version = hpxml_header.eri_calculation_version + n_occ = hpxml_bldg.building_occupancy.number_of_residents ltg_locns = [HPXML::LocationInterior, HPXML::LocationExterior, HPXML::LocationGarage] ltg_types = [HPXML::LightingTypeCFL, HPXML::LightingTypeLFL, HPXML::LightingTypeLED] @@ -39,7 +40,7 @@ def self.apply(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) fractions[[HPXML::LocationInterior, HPXML::LightingTypeLFL]], fractions[[HPXML::LocationInterior, HPXML::LightingTypeLED]]) end - int_kwh = 0.0 if int_kwh.nil? + int_kwh = 0.0 if int_kwh.nil? || n_occ == 0 int_kwh *= lighting.interior_usage_multiplier unless lighting.interior_usage_multiplier.nil? # Calculate exterior lighting kWh/yr @@ -50,7 +51,7 @@ def self.apply(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) fractions[[HPXML::LocationExterior, HPXML::LightingTypeLFL]], fractions[[HPXML::LocationExterior, HPXML::LightingTypeLED]]) end - ext_kwh = 0.0 if ext_kwh.nil? + ext_kwh = 0.0 if ext_kwh.nil? || n_occ == 0 ext_kwh *= lighting.exterior_usage_multiplier unless lighting.exterior_usage_multiplier.nil? ext_kwh *= unit_multiplier # Not in a thermal zone, so needs to be explicitly multiplied @@ -69,7 +70,7 @@ def self.apply(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) fractions[[HPXML::LocationGarage, HPXML::LightingTypeLED]]) end end - grg_kwh = 0.0 if grg_kwh.nil? + grg_kwh = 0.0 if grg_kwh.nil? || n_occ == 0 grg_kwh *= lighting.garage_usage_multiplier unless lighting.garage_usage_multiplier.nil? # Add lighting to conditioned space diff --git a/HPXMLtoOpenStudio/resources/misc_loads.rb b/HPXMLtoOpenStudio/resources/misc_loads.rb index 036c38707d..3419da11aa 100644 --- a/HPXMLtoOpenStudio/resources/misc_loads.rb +++ b/HPXMLtoOpenStudio/resources/misc_loads.rb @@ -12,6 +12,11 @@ module MiscLoads # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_plug_loads(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) + if hpxml_bldg.building_occupancy.number_of_residents == 0 + # Operational calculation w/ zero occupants, zero out energy use + return + end + hpxml_bldg.plug_loads.each do |plug_load| case plug_load.plug_load_type when HPXML::PlugLoadTypeOther diff --git a/HPXMLtoOpenStudio/tests/test_airflow.rb b/HPXMLtoOpenStudio/tests/test_airflow.rb index d67967fa04..da1c90dbb8 100644 --- a/HPXMLtoOpenStudio/tests/test_airflow.rb +++ b/HPXMLtoOpenStudio/tests/test_airflow.rb @@ -928,6 +928,26 @@ def test_duct_effective_r_values end end + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-residents-0.xml')) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # Check no natural ventilation or whole house fan + program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{Constants::ObjectTypeNaturalVentilation} program") + assert_equal(0, UnitConversions.convert(program_values['NVArea'].sum, 'cm^2', 'ft^2')) + assert_equal(0, UnitConversions.convert(program_values['WHF_Flow'].sum, 'm^3/s', 'cfm')) + + # Check no clothes dryer venting + program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{Constants::ObjectTypeInfiltration} program") + assert_equal(0, UnitConversions.convert(program_values['Qdryer'].sum, 'm^3/s', 'cfm')) + + # Check no kitchen/bath local ventilation + program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{Constants::ObjectTypeInfiltration} program") + assert_equal(0, UnitConversions.convert(program_values['Qrange'].sum, 'm^3/s', 'cfm')) + assert_equal(0, UnitConversions.convert(program_values['Qbath'].sum, 'm^3/s', 'cfm')) + end + def _test_measure(args_hash) # create an instance of the measure measure = HPXMLtoOpenStudio.new diff --git a/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb b/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb index 20baadd275..619be06570 100644 --- a/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +++ b/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb @@ -952,6 +952,28 @@ def test_usage_multiplier assert_in_epsilon(1.0, get_oe_fractions(model, Constants::ObjectTypeGeneralWaterUseLatent)[1], 0.001) end + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-0.xml')) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # water use equipment hot water gal/day + assert_equal(0, get_wu_gpd(model, Constants::ObjectTypeClothesWasher)) + assert_equal(0, get_wu_gpd(model, Constants::ObjectTypeDishwasher)) + assert_equal(0, get_wu_gpd(model, Constants::ObjectTypeFixtures)) + assert_equal(0, get_wu_gpd(model, Constants::ObjectTypeDistributionWaste)) + + # electric equipment + assert_equal(0, get_ee_kwh_per_year(model, Constants::ObjectTypeClothesWasher)) + assert_equal(0, get_ee_kwh_per_year(model, Constants::ObjectTypeDishwasher)) + assert_equal(0, get_ee_kwh_per_year(model, Constants::ObjectTypeClothesDryer)) + assert_equal(0, get_ee_kwh_per_year(model, Constants::ObjectTypeCookingRange)) + + # other equipment + assert_equal(0, get_oe_kwh(model, Constants::ObjectTypeGeneralWaterUseSensible)) + assert_equal(0, get_oe_kwh(model, Constants::ObjectTypeGeneralWaterUseLatent)) + end + def test_operational_1_occupant args_hash = {} args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-1.xml')) diff --git a/HPXMLtoOpenStudio/tests/test_lighting.rb b/HPXMLtoOpenStudio/tests/test_lighting.rb index 9c92c57028..467f8acc41 100644 --- a/HPXMLtoOpenStudio/tests/test_lighting.rb +++ b/HPXMLtoOpenStudio/tests/test_lighting.rb @@ -133,6 +133,21 @@ def test_ceiling_fan assert_in_delta(200, get_kwh_per_year(model, Constants::ObjectTypeCeilingFan), 1.0) end + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-0.xml')) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # Check interior lighting + assert_equal(0.0, get_kwh_per_year(model, Constants::ObjectTypeLightingInterior)) + + # Check garage lighting + assert_equal(0.0, get_kwh_per_year(model, Constants::ObjectTypeLightingGarage)) + + # Check exterior lighting + assert_equal(0.0, get_kwh_per_year(model, Constants::ObjectTypeLightingExterior)) + end + def _test_measure(args_hash) # create an instance of the measure measure = HPXMLtoOpenStudio.new diff --git a/HPXMLtoOpenStudio/tests/test_miscloads.rb b/HPXMLtoOpenStudio/tests/test_miscloads.rb index b8e0121688..66e03f7376 100644 --- a/HPXMLtoOpenStudio/tests/test_miscloads.rb +++ b/HPXMLtoOpenStudio/tests/test_miscloads.rb @@ -195,7 +195,68 @@ def test_large_uncommon_loads2 assert_in_delta(55, therm_yr, 1.0) end - def test_operational_defaults + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-0.xml')) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # Check misc plug loads + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPlugLoads) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check television + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscTelevision) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check vehicle + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscElectricVehicleCharging) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check well pump + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscWellPump) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check pool pump + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPoolPump) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check pool heater + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPoolHeater) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check permanent spa pump + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPermanentSpaPump) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check permanent spa heater + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPermanentSpaHeater) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check grill + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscGrill) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check lighting + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscLighting) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + + # Check fireplace + kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscFireplace) + assert_equal(0, kwh_yr) + assert_equal(0, therm_yr) + end + + def test_operational_5_5_occupants args_hash = {} args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-5-5.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) diff --git a/workflow/hpxml_inputs.json b/workflow/hpxml_inputs.json index 443c200788..0d0bdac382 100644 --- a/workflow/hpxml_inputs.json +++ b/workflow/hpxml_inputs.json @@ -3699,10 +3699,6 @@ "parent_hpxml": "sample_files/base.xml", "geometry_unit_num_occupants": 0 }, - "sample_files/base-residents-0-runperiod-1-month.xml": { - "parent_hpxml": "sample_files/base-residents-0.xml", - "simulation_control_run_period": "Feb 1 - Feb 28" - }, "sample_files/base-residents-1.xml": { "parent_hpxml": "sample_files/base.xml", "geometry_unit_num_occupants": 1, diff --git a/workflow/sample_files/base-residents-0-runperiod-1-month.xml b/workflow/sample_files/base-residents-0-runperiod-1-month.xml deleted file mode 100644 index 0c03c64524..0000000000 --- a/workflow/sample_files/base-residents-0-runperiod-1-month.xml +++ /dev/null @@ -1,558 +0,0 @@ - - - - HPXML - tasks.rb - 2000-01-01T00:00:00-07:00 - create - - - - - 60 - 2 - 1 - 2 - 28 - - - - Bills - - - - - - - - -
- CO -
-
- - proposed workscope - - - - - suburban - stand-alone - no units above or below - 180 - - electricity - natural gas - - - - 0.0 - - - single-family detached - 2.0 - 1.0 - 8.0 - 3 - 2 - 2700.0 - 21600.0 - - - - - 2006 - 5B - - - - USA_CO_Denver.Intl.AP.725650_TMY3 - - USA_CO_Denver.Intl.AP.725650_TMY3.epw - - - - - - - - 50.0 - - ACH - 3.0 - - 21600.0 - - - - - - - - false - - - false - - - - - - - - - - - true - - - - - - - - - - - attic - unvented - 1509.3 - asphalt or fiberglass shingles - 0.7 - 0.92 - 6.0 - - - 2.3 - - - - - - - outside - basement - conditioned - 115.6 - wood siding - 0.7 - 0.92 - - - 23.0 - - - - - - - outside - conditioned space - - - - 1200.0 - wood siding - 0.7 - 0.92 - - gypsum board - - - - 23.0 - - - - - outside - attic - unvented - gable - - - - 225.0 - wood siding - 0.7 - 0.92 - - - 4.0 - - - - - - - ground - basement - conditioned - 8.0 - 1200.0 - 8.0 - 7.0 - - gypsum board - - - - - continuous - exterior - 8.9 - 0.0 - 8.0 - - - continuous - interior - 0.0 - - - - - - - - attic - unvented - conditioned space - ceiling - - - - 1350.0 - - gypsum board - - - - 39.3 - - - - - - - basement - conditioned - 1350.0 - 4.0 - 150.0 - - - - 0.0 - 0.0 - - - - - - 0.0 - 0.0 - - - - 0.0 - 0.0 - - - - - - - 108.0 - 0 - 0.33 - 0.45 - - - 0.7 - 0.85 - - 0.67 - - - - - 72.0 - 90 - 0.33 - 0.45 - - - 0.7 - 0.85 - - 0.67 - - - - - 108.0 - 180 - 0.33 - 0.45 - - - 0.7 - 0.85 - - 0.67 - - - - - 72.0 - 270 - 0.33 - 0.45 - - - 0.7 - 0.85 - - 0.67 - - - - - - - - 40.0 - 180 - 4.4 - - - - - - - - - - - - - - - - - natural gas - 36000.0 - - AFUE - 0.92 - - 1.0 - - - - - central air conditioner - electricity - 24000.0 - single stage - 1.0 - - SEER - 13.0 - - 0.73 - - - - - 68.0 - 78.0 - - - - - - regular velocity - - supply - - CFM25 - 75.0 - to outside - - - - return - - CFM25 - 25.0 - to outside - - - - - supply - 4.0 - attic - unvented - 150.0 - - - - return - 0.0 - attic - unvented - 50.0 - - - - - - - - - electricity - storage water heater - conditioned space - 40.0 - 1.0 - 18767.0 - 0.95 - 125.0 - - - - - - 50.0 - - - - 0.0 - - - - - shower head - true - - - - faucet - false - - - - - - - conditioned space - 1.21 - 380.0 - 0.12 - 1.09 - 27.0 - 6.0 - 3.2 - - - - conditioned space - electricity - 3.73 - true - 150.0 - - - - conditioned space - 307.0 - 12 - 0.12 - 1.09 - 22.32 - 4.0 - - - - conditioned space - 650.0 - - - - conditioned space - electricity - false - - - - false - - - - - - interior - 0.4 - - - - - - - interior - 0.1 - - - - - - - interior - 0.25 - - - - - - - exterior - 0.4 - - - - - - - exterior - 0.1 - - - - - - - exterior - 0.25 - - - - - - - - - TV other - - kWh/year - 620.0 - - - - - other - - kWh/year - 2457.0 - - - 0.855 - 0.045 - - - - -
-
\ No newline at end of file From b17f24ee7681eda50cbe213a85a088caff5b0505 Mon Sep 17 00:00:00 2001 From: Scott Horowitz Date: Tue, 17 Dec 2024 14:21:47 -0700 Subject: [PATCH 2/6] Fix ASHRAE 140 runs. --- HPXMLtoOpenStudio/measure.xml | 6 +++--- HPXMLtoOpenStudio/resources/misc_loads.rb | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index dfcd69c776..bd36e2924f 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - dc3b4a16-16a9-4daa-a9ca-fc8e0bcda42c - 2024-12-17T20:11:12Z + f6215039-69e4-4cc9-a911-32c6e2db4759 + 2024-12-17T21:18:42Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -441,7 +441,7 @@ misc_loads.rb rb resource - A4F201D8 + 039B0042
model.rb diff --git a/HPXMLtoOpenStudio/resources/misc_loads.rb b/HPXMLtoOpenStudio/resources/misc_loads.rb index 3419da11aa..53aa99f416 100644 --- a/HPXMLtoOpenStudio/resources/misc_loads.rb +++ b/HPXMLtoOpenStudio/resources/misc_loads.rb @@ -12,7 +12,7 @@ module MiscLoads # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_plug_loads(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) - if hpxml_bldg.building_occupancy.number_of_residents == 0 + if hpxml_bldg.building_occupancy.number_of_residents == 0 && (not hpxml_header.apply_ashrae140_assumptions) # Operational calculation w/ zero occupants, zero out energy use return end From 01b93fb883cb2883c7d17746f017ad4c83ef6d3a Mon Sep 17 00:00:00 2001 From: GitHub Action Date: Tue, 17 Dec 2024 22:11:31 +0000 Subject: [PATCH 3/6] Latest results. --- workflow/tests/base_results/results_simulations_bills.csv | 1 - workflow/tests/base_results/results_simulations_energy.csv | 1 - workflow/tests/base_results/results_simulations_hvac.csv | 1 - workflow/tests/base_results/results_simulations_loads.csv | 1 - workflow/tests/base_results/results_simulations_misc.csv | 1 - 5 files changed, 5 deletions(-) diff --git a/workflow/tests/base_results/results_simulations_bills.csv b/workflow/tests/base_results/results_simulations_bills.csv index efd5712afc..342ba17740 100644 --- a/workflow/tests/base_results/results_simulations_bills.csv +++ b/workflow/tests/base_results/results_simulations_bills.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,955.78,144.0,1068.19,-978.65,233.54,144 base-pv-generators-battery.xml,924.45,144.0,1036.86,-978.65,202.21,144.0,338.28,482.28,0.0,239.96,239.96,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-pv-generators.xml,892.64,144.0,1005.05,-978.65,170.4,144.0,338.28,482.28,0.0,239.96,239.96,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-pv.xml,861.79,144.0,1303.13,-978.65,468.48,144.0,249.31,393.31,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -base-residents-0-runperiod-1-month.xml,130.03,12.0,18.35,0.0,30.35,12.0,87.68,99.68,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-0.xml,915.08,144.0,268.02,0.0,412.02,144.0,359.06,503.06,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-1-misc-loads-large-uncommon.xml,2674.4,144.0,1817.12,0.0,1961.12,144.0,443.44,587.44,0.0,0.0,0.0,0.0,67.32,67.32,0.0,58.52,58.52,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-1-misc-loads-large-uncommon2.xml,2404.07,144.0,1731.6,0.0,1875.6,144.0,254.61,398.61,0.0,71.34,71.34,0.0,0.0,0.0,0.0,0.0,0.0,0.0,58.52,58.52,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_simulations_energy.csv b/workflow/tests/base_results/results_simulations_energy.csv index f231923ff7..c33851605c 100644 --- a/workflow/tests/base_results/results_simulations_energy.csv +++ b/workflow/tests/base_results/results_simulations_energy.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,78.352,43.276,37.536,2.46,32.316,8.5,0. base-pv-generators-battery.xml,77.491,42.415,36.675,1.599,32.316,8.5,0.0,0.0,0.0,0.0,0.0,0.591,0.0,0.0,4.398,0.662,9.013,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.072,0.0,0.0,0.319,0.365,1.513,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,-26.886,-8.189,0.874,23.816,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-pv-generators.xml,76.617,41.541,35.801,0.725,32.316,8.5,0.0,0.0,0.0,0.0,0.0,0.591,0.0,0.0,4.398,0.662,9.013,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.072,0.0,0.0,0.319,0.365,1.513,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,-26.886,-8.189,0.0,23.816,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.5,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-pv.xml,59.617,32.73,35.801,8.914,23.816,0.0,0.0,0.0,0.0,0.0,0.0,0.591,0.0,0.0,4.398,0.662,9.013,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,2.072,0.0,0.0,0.319,0.365,1.513,1.529,0.0,2.116,8.384,0.0,0.0,0.0,0.0,0.0,0.0,-26.886,0.0,0.0,23.816,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 -base-residents-0-runperiod-1-month.xml,8.8797,8.8797,0.504,0.504,8.3757,0.0,0.0,0.0,0.0,0.0,0.0,0.2078,0.0,0.0,0.1034,0.0,0.0468,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.146,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,8.3757,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-0.xml,41.664,41.664,7.363,7.363,34.301,0.0,0.0,0.0,0.0,0.0,0.0,0.851,0.0,0.0,3.398,0.481,0.577,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.056,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,34.301,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-1-misc-loads-large-uncommon.xml,99.944,99.944,49.922,49.922,42.362,0.0,2.527,5.133,0.0,0.0,0.0,0.565,0.0,0.0,4.562,0.695,3.75,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,4.293,1.024,0.0,0.2,0.221,0.917,1.115,0.0,2.007,6.55,5.687,1.15,0.0,6.508,2.937,2.899,0.0,0.0,0.0,22.778,0.0,0.0,0.0,0.0,0.0,18.039,0.0,0.0,1.544,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.527,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.133,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-1-misc-loads-large-uncommon2.xml,79.555,79.555,47.572,47.572,24.322,2.527,0.0,0.0,5.133,0.0,0.0,0.565,0.0,0.0,4.562,0.695,3.75,0.0,0.0,4.507,0.0,0.334,0.0,0.0,0.0,0.0,4.293,1.024,0.0,0.2,0.221,0.917,1.115,0.0,2.007,6.55,5.687,1.15,0.0,6.508,0.587,2.899,0.0,0.0,0.0,22.778,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,1.544,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,2.527,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,5.133,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 diff --git a/workflow/tests/base_results/results_simulations_hvac.csv b/workflow/tests/base_results/results_simulations_hvac.csv index 0377e4c151..d85488c244 100644 --- a/workflow/tests/base_results/results_simulations_hvac.csv +++ b/workflow/tests/base_results/results_simulations_hvac.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8 base-pv-generators-battery.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-pv-generators.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-pv.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 -base-residents-0-runperiod-1-month.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-residents-0.xml,6.8,91.76,36000.0,24000.0,0.0,32239.0,8709.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,0.0,0.0,20039.0,6112.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,3320.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-residents-1-misc-loads-large-uncommon.xml,6.8,91.76,36000.0,24000.0,0.0,33431.0,8742.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,5779.0,0.0,0.0,21277.0,6150.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,4520.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 base-residents-1-misc-loads-large-uncommon2.xml,6.8,91.76,36000.0,24000.0,0.0,33431.0,8742.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,5779.0,0.0,0.0,21277.0,6150.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,0.0,4520.0,0.0,0.0,139.0,0.0,-661.0,0.0,800.0 diff --git a/workflow/tests/base_results/results_simulations_loads.csv b/workflow/tests/base_results/results_simulations_loads.csv index fe9e046176..7e033826de 100644 --- a/workflow/tests/base_results/results_simulations_loads.csv +++ b/workflow/tests/base_results/results_simulations_loads.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,22.503,0.0,13.745,9.07,0.615,0.0,0.0,0. base-pv-generators-battery.xml,22.503,0.0,13.745,9.07,0.615,0.0,0.0,0.0,3.819,3.882,0.545,7.57,0.682,10.76,-13.571,0.0,0.0,0.0,8.363,-0.116,5.259,0.0,0.77,0.0,5.323,-8.475,-2.662,0.0,0.029,-0.188,-0.014,2.827,0.035,-0.632,10.837,0.0,0.0,0.0,-6.138,-0.112,-0.847,-3.884,-0.117,0.0,3.113,7.106,1.845 base-pv-generators.xml,22.503,0.0,13.745,9.07,0.615,0.0,0.0,0.0,3.819,3.882,0.545,7.57,0.682,10.76,-13.571,0.0,0.0,0.0,8.363,-0.116,5.259,0.0,0.77,0.0,5.323,-8.475,-2.662,0.0,0.029,-0.188,-0.014,2.827,0.035,-0.632,10.837,0.0,0.0,0.0,-6.138,-0.112,-0.847,-3.884,-0.117,0.0,3.113,7.106,1.845 base-pv.xml,22.503,0.0,13.745,9.07,0.615,0.0,0.0,0.0,3.819,3.882,0.545,7.57,0.682,10.76,-13.571,0.0,0.0,0.0,8.363,-0.116,5.259,0.0,0.77,0.0,5.323,-8.475,-2.662,0.0,0.029,-0.188,-0.014,2.827,0.035,-0.632,10.837,0.0,0.0,0.0,-6.138,-0.112,-0.847,-3.884,-0.117,0.0,3.113,7.106,1.845 -base-residents-0-runperiod-1-month.xml,7.9107,0.0,0.0,0.0,0.0511,0.0,0.0,0.0,0.5914,0.643,0.0909,1.746,0.1095,1.7781,-1.988,0.0,0.0,0.0,2.2357,-0.0004,1.0461,0.0,0.0,0.0,1.8131,-0.1971,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0 base-residents-0.xml,32.415,0.0,10.561,0.0,0.62,0.0,0.0,0.0,3.761,3.912,0.547,7.099,0.683,10.947,-14.892,0.0,0.0,0.0,8.358,-0.174,6.026,0.0,0.0,0.0,7.39,-1.573,0.0,0.0,0.311,0.056,0.019,3.03,0.087,0.17,9.539,0.0,0.0,0.0,-5.202,-0.169,-0.644,0.0,0.0,0.0,2.393,1.102,0.0 base-residents-1-misc-loads-large-uncommon.xml,21.522,0.0,14.588,3.416,0.614,0.0,0.0,0.0,3.822,3.877,0.545,7.617,0.681,10.741,-13.462,0.0,0.0,0.0,8.416,-0.111,5.233,0.0,0.766,0.0,5.114,-9.432,-2.643,0.0,-0.024,-0.232,-0.02,2.761,0.024,-0.764,10.946,0.0,0.0,0.0,-6.251,-0.107,-0.887,-4.03,-0.122,0.0,3.256,8.291,1.864 base-residents-1-misc-loads-large-uncommon2.xml,21.522,0.0,14.588,3.416,0.614,0.0,0.0,0.0,3.822,3.877,0.545,7.617,0.681,10.741,-13.462,0.0,0.0,0.0,8.416,-0.111,5.233,0.0,0.766,0.0,5.114,-9.432,-2.643,0.0,-0.024,-0.232,-0.02,2.761,0.024,-0.764,10.946,0.0,0.0,0.0,-6.251,-0.107,-0.887,-4.03,-0.122,0.0,3.256,8.291,1.864 diff --git a/workflow/tests/base_results/results_simulations_misc.csv b/workflow/tests/base_results/results_simulations_misc.csv index a942301e78..7babdf768c 100644 --- a/workflow/tests/base_results/results_simulations_misc.csv +++ b/workflow/tests/base_results/results_simulations_misc.csv @@ -411,7 +411,6 @@ base-pv-generators-battery-scheduled.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,208 base-pv-generators-battery.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2125.8,3715.9,3715.9,23.71,18.744,80.224 base-pv-generators.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2082.5,3612.6,3612.6,23.71,18.744,0.0 base-pv.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2082.5,3612.6,3612.6,23.71,18.744,0.0 -base-residents-0-runperiod-1-month.xml,0.0,0.0,0.0,0.0,0.0,0.0,627.96,0.0,627.96,27.1458,0.0,0.0 base-residents-0.xml,0.0,0.0,0.0,0.0,0.0,0.0,609.5,1840.9,1840.9,25.712,14.806,0.0 base-residents-1-misc-loads-large-uncommon.xml,0.0,0.0,821.3,625.4,3446.7,1167.8,2361.4,4228.7,4228.7,23.649,19.133,0.0 base-residents-1-misc-loads-large-uncommon2.xml,0.0,0.0,821.3,625.4,3446.7,1167.8,2242.3,4045.5,4045.5,23.649,19.133,0.0 From 2ca07befda73ab346738df93f01e63262e748b94 Mon Sep 17 00:00:00 2001 From: Scott Horowitz Date: Wed, 18 Dec 2024 15:01:26 -0700 Subject: [PATCH 4/6] Bugfixes and more tests. --- HPXMLtoOpenStudio/measure.xml | 14 +++--- HPXMLtoOpenStudio/resources/airflow.rb | 6 +-- HPXMLtoOpenStudio/resources/defaults.rb | 8 ++-- HPXMLtoOpenStudio/resources/misc_loads.rb | 10 ++++ HPXMLtoOpenStudio/tests/test_airflow.rb | 10 +++- HPXMLtoOpenStudio/tests/test_miscloads.rb | 58 ++++++++++++++++++----- 6 files changed, 79 insertions(+), 27 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index bd36e2924f..b29acf72ee 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - f6215039-69e4-4cc9-a911-32c6e2db4759 - 2024-12-17T21:18:42Z + 7501d101-5f21-4eea-82f1-a443717c2359 + 2024-12-18T22:00:21Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -189,7 +189,7 @@ airflow.rb rb resource - 06E4A131 + 14A94278 battery.rb @@ -327,7 +327,7 @@ defaults.rb rb resource - CADAF9FE + 7EE4828A energyplus.rb @@ -441,7 +441,7 @@ misc_loads.rb rb resource - 039B0042 + 5A23B058 model.rb @@ -651,7 +651,7 @@ test_airflow.rb rb test - 6BDC58E4 + FAED863F test_battery.rb @@ -711,7 +711,7 @@ test_miscloads.rb rb test - 784CC382 + 52ADD231 test_pv.rb diff --git a/HPXMLtoOpenStudio/resources/airflow.rb b/HPXMLtoOpenStudio/resources/airflow.rb index 8709970c39..c4f4056ad3 100644 --- a/HPXMLtoOpenStudio/resources/airflow.rb +++ b/HPXMLtoOpenStudio/resources/airflow.rb @@ -38,10 +38,8 @@ def self.apply(runner, model, weather, spaces, hpxml_bldg, hpxml_header, schedul elsif f.used_for_seasonal_cooling_load_reduction vent_fans[:whf] << f elsif f.used_for_local_ventilation - if hpxml_bldg.building_occupancy.number_of_residents == 0 - # Operational calculation w/ zero occupants, zero out energy use - continue - end + next if hpxml_bldg.building_occupancy.number_of_residents == 0 # Operational calculation w/ zero occupants, zero out energy use + if f.fan_location == HPXML::LocationKitchen vent_fans[:kitchen] << f elsif f.fan_location == HPXML::LocationBath diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb index 841bc497d1..2f5a4ca339 100644 --- a/HPXMLtoOpenStudio/resources/defaults.rb +++ b/HPXMLtoOpenStudio/resources/defaults.rb @@ -5763,7 +5763,7 @@ def self.get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type) load_units = HPXML::UnitsKwhPerYear if n_occ == 0 # Operational calculation w/ zero occupants, zero out energy use - return load_type, 0.0 + return load_units, 0.0 end load_value = 8.3 / 0.004 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr @@ -5774,7 +5774,7 @@ def self.get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type) load_units = HPXML::UnitsThermPerYear if n_occ == 0 # Operational calculation w/ zero occupants, zero out energy use - return load_type, 0.0 + return load_units, 0.0 end load_value = 3.0 / 0.014 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # therm/yr @@ -5817,7 +5817,7 @@ def self.get_permanent_spa_heater_annual_energy(cfa, nbeds, n_occ, unit_type, ty load_units = HPXML::UnitsKwhPerYear if n_occ == 0 # Operational calculation w/ zero occupants, zero out energy use - return load_type, 0.0 + return load_units, 0.0 end load_value = 49.0 / 0.048 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr @@ -5828,7 +5828,7 @@ def self.get_permanent_spa_heater_annual_energy(cfa, nbeds, n_occ, unit_type, ty load_units = HPXML::UnitsThermPerYear if n_occ == 0 # Operational calculation w/ zero occupants, zero out energy use - return load_type, 0.0 + return load_units, 0.0 end load_value = 0.87 / 0.011 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # therm/yr diff --git a/HPXMLtoOpenStudio/resources/misc_loads.rb b/HPXMLtoOpenStudio/resources/misc_loads.rb index 53aa99f416..1b16344f16 100644 --- a/HPXMLtoOpenStudio/resources/misc_loads.rb +++ b/HPXMLtoOpenStudio/resources/misc_loads.rb @@ -117,6 +117,11 @@ def self.apply_plug_load(runner, model, plug_load, obj_name, spaces, schedules_f # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_fuel_loads(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) + if hpxml_bldg.building_occupancy.number_of_residents == 0 + # Operational calculation w/ zero occupants, zero out energy use + return + end + hpxml_bldg.fuel_loads.each do |fuel_load| case fuel_load.fuel_load_type when HPXML::FuelLoadTypeGrill @@ -206,6 +211,11 @@ def self.apply_fuel_load(runner, model, fuel_load, obj_name, spaces, schedules_f # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_pools_and_permanent_spas(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) + if hpxml_bldg.building_occupancy.number_of_residents == 0 + # Operational calculation w/ zero occupants, zero out energy use + return + end + (hpxml_bldg.pools + hpxml_bldg.permanent_spas).each do |pool_or_spa| next if pool_or_spa.type == HPXML::TypeNone diff --git a/HPXMLtoOpenStudio/tests/test_airflow.rb b/HPXMLtoOpenStudio/tests/test_airflow.rb index da1c90dbb8..fa26004a0b 100644 --- a/HPXMLtoOpenStudio/tests/test_airflow.rb +++ b/HPXMLtoOpenStudio/tests/test_airflow.rb @@ -930,7 +930,15 @@ def test_duct_effective_r_values def test_operational_0_occupants args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-residents-0.xml')) + args_hash['hpxml_path'] = @tmp_hpxml_path + hpxml, hpxml_bldg = _create_hpxml('base-residents-0.xml') + hpxml_bldg.ventilation_fans.add(id: "VentilationFan#{hpxml_bldg.ventilation_fans.size + 1}", + fan_location: HPXML::LocationBath, + used_for_local_ventilation: true) + hpxml_bldg.ventilation_fans.add(id: "VentilationFan#{hpxml_bldg.ventilation_fans.size + 1}", + fan_location: HPXML::LocationKitchen, + used_for_local_ventilation: true) + XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check no natural ventilation or whole house fan diff --git a/HPXMLtoOpenStudio/tests/test_miscloads.rb b/HPXMLtoOpenStudio/tests/test_miscloads.rb index 66e03f7376..39c25df13d 100644 --- a/HPXMLtoOpenStudio/tests/test_miscloads.rb +++ b/HPXMLtoOpenStudio/tests/test_miscloads.rb @@ -8,15 +8,18 @@ require_relative '../resources/util.rb' class HPXMLtoOpenStudioMiscLoadsTest < Minitest::Test + def setup + @root_path = File.absolute_path(File.join(File.dirname(__FILE__), '..', '..')) + @sample_files_path = File.join(@root_path, 'workflow', 'sample_files') + @tmp_hpxml_path = File.join(@sample_files_path, 'tmp.xml') + end + def teardown + File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end - def sample_files_dir - return File.join(File.dirname(__FILE__), '..', '..', 'workflow', 'sample_files') - end - def get_kwh_therm_per_year(model, name) kwh_yr = 0.0 therm_yr = 0.0 @@ -43,7 +46,7 @@ def get_kwh_therm_per_year(model, name) def test_misc_loads args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check misc plug loads @@ -75,7 +78,7 @@ def test_misc_loads def test_large_uncommon_loads args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-misc-loads-large-uncommon.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-misc-loads-large-uncommon.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check misc plug loads @@ -136,7 +139,7 @@ def test_large_uncommon_loads def test_large_uncommon_loads2 args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-misc-loads-large-uncommon2.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-misc-loads-large-uncommon2.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check misc plug loads @@ -197,7 +200,35 @@ def test_large_uncommon_loads2 def test_operational_0_occupants args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-0.xml')) + args_hash['hpxml_path'] = @tmp_hpxml_path + hpxml, hpxml_bldg = _create_hpxml('base-residents-0.xml') + [HPXML::PlugLoadTypeElectricVehicleCharging, + HPXML::PlugLoadTypeWellPump].each do |plug_load_type| + hpxml_bldg.plug_loads.add(id: "PlugLoad#{hpxml_bldg.plug_loads.size + 1}", + plug_load_type: plug_load_type) + end + [HPXML::FuelLoadTypeFireplace, + HPXML::FuelLoadTypeGrill, + HPXML::FuelLoadTypeLighting].each do |fuel_load_type| + hpxml_bldg.fuel_loads.add(id: "FuelLoad#{hpxml_bldg.fuel_loads.size + 1}", + fuel_type: HPXML::FuelTypeNaturalGas, + fuel_load_type: fuel_load_type, + therm_per_year: 100) + end + hpxml_bldg.pools.add(id: "Pool#{hpxml_bldg.pools.size + 1}", + type: HPXML::TypeUnknown, + pump_type: HPXML::TypeUnknown, + heater_type: HPXML::HeaterTypeGas, + heater_load_units: HPXML::UnitsThermPerYear) + hpxml_bldg.permanent_spas.add(id: "PermanentSpa#{hpxml_bldg.permanent_spas.size + 1}", + type: HPXML::TypeUnknown, + pump_type: HPXML::TypeUnknown, + pump_kwh_per_year: 100, + heater_type: HPXML::HeaterTypeElectricResistance, + heater_load_units: HPXML::UnitsKwhPerYear, + heater_load_value: 100) + + XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check misc plug loads @@ -258,7 +289,7 @@ def test_operational_0_occupants def test_operational_5_5_occupants args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-5-5.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-residents-5-5.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check misc plug loads @@ -319,7 +350,7 @@ def test_operational_5_5_occupants def test_operational_large_uncommon_loads args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-1-misc-loads-large-uncommon.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-residents-1-misc-loads-large-uncommon.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check misc plug loads @@ -380,7 +411,7 @@ def test_operational_large_uncommon_loads def test_operational_large_uncommon_loads2 args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-1-misc-loads-large-uncommon2.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-residents-1-misc-loads-large-uncommon2.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check misc plug loads @@ -476,4 +507,9 @@ def _test_measure(args_hash) return model, hpxml, hpxml.buildings[0] end + + def _create_hpxml(hpxml_name) + hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, hpxml_name)) + return hpxml, hpxml.buildings[0] + end end From 4616266ebf490f5275fdf4b0f59550b8e88030e4 Mon Sep 17 00:00:00 2001 From: Scott Horowitz Date: Thu, 19 Dec 2024 11:30:11 -0700 Subject: [PATCH 5/6] Exclude pool/spa and include ceiling fan to match previous implementation. --- HPXMLtoOpenStudio/measure.xml | 44 +++++++++---------- HPXMLtoOpenStudio/resources/defaults.rb | 30 ------------- HPXMLtoOpenStudio/resources/hvac.rb | 12 +++-- HPXMLtoOpenStudio/resources/misc_loads.rb | 5 --- HPXMLtoOpenStudio/tests/test_airflow.rb | 1 + HPXMLtoOpenStudio/tests/test_battery.rb | 1 + HPXMLtoOpenStudio/tests/test_defaults.rb | 1 + HPXMLtoOpenStudio/tests/test_enclosure.rb | 1 + HPXMLtoOpenStudio/tests/test_generator.rb | 1 + .../tests/test_hotwater_appliance.rb | 1 + HPXMLtoOpenStudio/tests/test_hvac.rb | 27 ++++++++++++ HPXMLtoOpenStudio/tests/test_hvac_sizing.rb | 3 +- HPXMLtoOpenStudio/tests/test_lighting.rb | 39 +++++++++++----- HPXMLtoOpenStudio/tests/test_location.rb | 1 + HPXMLtoOpenStudio/tests/test_miscloads.rb | 9 ++-- HPXMLtoOpenStudio/tests/test_pv.rb | 1 + HPXMLtoOpenStudio/tests/test_schedules.rb | 1 + HPXMLtoOpenStudio/tests/test_simcontrols.rb | 1 + HPXMLtoOpenStudio/tests/test_validation.rb | 1 + HPXMLtoOpenStudio/tests/test_water_heater.rb | 1 + HPXMLtoOpenStudio/tests/test_weather.rb | 1 + 21 files changed, 105 insertions(+), 77 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index b29acf72ee..05e680e9c3 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 7501d101-5f21-4eea-82f1-a443717c2359 - 2024-12-18T22:00:21Z + 0bff6a77-c10a-4a70-bb9b-4b1efdb32682 + 2024-12-19T18:29:02Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -327,7 +327,7 @@ defaults.rb rb resource - 7EE4828A + F2AE9AD3 energyplus.rb @@ -387,7 +387,7 @@ hvac.rb rb resource - 0F2DDAA0 + 759FC93A hvac_sizing.rb @@ -441,7 +441,7 @@ misc_loads.rb rb resource - 5A23B058 + F66475DC model.rb @@ -651,103 +651,103 @@ test_airflow.rb rb test - FAED863F + AF85CB1C test_battery.rb rb test - 3DF46EDF + E8640271 test_defaults.rb rb test - 1004443C + D57EF59F test_enclosure.rb rb test - A5253262 + 2DA78F4F test_generator.rb rb test - 67DD47BA + F540F8F8 test_hotwater_appliance.rb rb test - 27A0085A + B02084FA test_hvac.rb rb test - 994A2553 + 7954392A test_hvac_sizing.rb rb test - E1BC3865 + E018D108 test_lighting.rb rb test - 5300BCE3 + 8CC5D6BC test_location.rb rb test - 1BABD0AE + 733BB792 test_miscloads.rb rb test - 52ADD231 + CBD61753 test_pv.rb rb test - EC9BA2EB + 48F8F1FF test_schedules.rb rb test - 62B8CE90 + BDA04315 test_simcontrols.rb rb test - 914A44BF + B15BFB90 test_validation.rb rb test - 95476C6B + 86EC5703 test_water_heater.rb rb test - A293B678 + 60CD4A1F test_weather.rb rb test - 7DCA4233 + AD9AB5EC util.rb diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb index 2f5a4ca339..696b614e4d 100644 --- a/HPXMLtoOpenStudio/resources/defaults.rb +++ b/HPXMLtoOpenStudio/resources/defaults.rb @@ -5736,11 +5736,6 @@ def self.get_televisions_values(cfa, nbeds, n_occ = nil, unit_type = nil) # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (kWh/yr) def self.get_pool_pump_annual_energy(cfa, nbeds, n_occ, unit_type) - if n_occ == 0 - # Operational calculation w/ zero occupants, zero out energy use - return 0.0 - end - nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) return 158.6 / 0.070 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) @@ -5761,22 +5756,12 @@ def self.get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type) load_value = nil if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include? type load_units = HPXML::UnitsKwhPerYear - if n_occ == 0 - # Operational calculation w/ zero occupants, zero out energy use - return load_units, 0.0 - end - load_value = 8.3 / 0.004 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr if type == HPXML::HeaterTypeHeatPump load_value /= 5.0 # Assume seasonal COP of 5.0 per https://www.energy.gov/energysaver/heat-pump-swimming-pool-heaters end elsif type == HPXML::HeaterTypeGas load_units = HPXML::UnitsThermPerYear - if n_occ == 0 - # Operational calculation w/ zero occupants, zero out energy use - return load_units, 0.0 - end - load_value = 3.0 / 0.014 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # therm/yr end return load_units, load_value @@ -5790,11 +5775,6 @@ def self.get_pool_heater_annual_energy(cfa, nbeds, n_occ, unit_type, type) # @param unit_type [String] Type of dwelling unit (HXPML::ResidentialTypeXXX) # @return [Double] Annual energy use (kWh/yr) def self.get_permanent_spa_pump_annual_energy(cfa, nbeds, n_occ, unit_type) - if n_occ == 0 - # Operational calculation w/ zero occupants, zero out energy use - return 0.0 - end - nbeds_eq = Defaults.get_equivalent_nbeds(nbeds, n_occ, unit_type) return 59.5 / 0.059 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr @@ -5815,22 +5795,12 @@ def self.get_permanent_spa_heater_annual_energy(cfa, nbeds, n_occ, unit_type, ty load_value = nil if [HPXML::HeaterTypeElectricResistance, HPXML::HeaterTypeHeatPump].include? type load_units = HPXML::UnitsKwhPerYear - if n_occ == 0 - # Operational calculation w/ zero occupants, zero out energy use - return load_units, 0.0 - end - load_value = 49.0 / 0.048 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # kWh/yr if type == HPXML::HeaterTypeHeatPump load_value /= 5.0 # Assume seasonal COP of 5.0 per https://www.energy.gov/energysaver/heat-pump-swimming-pool-heaters end elsif type == HPXML::HeaterTypeGas load_units = HPXML::UnitsThermPerYear - if n_occ == 0 - # Operational calculation w/ zero occupants, zero out energy use - return load_units, 0.0 - end - load_value = 0.87 / 0.011 * (0.5 + 0.25 * nbeds_eq / 3.0 + 0.25 * cfa / 1920.0) # therm/yr end return load_units, load_value diff --git a/HPXMLtoOpenStudio/resources/hvac.rb b/HPXMLtoOpenStudio/resources/hvac.rb index 6e91052f60..61b3939cce 100644 --- a/HPXMLtoOpenStudio/resources/hvac.rb +++ b/HPXMLtoOpenStudio/resources/hvac.rb @@ -1284,6 +1284,10 @@ def self.apply_dehumidifiers(runner, model, spaces, hpxml_bldg, hpxml_header) # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_ceiling_fans(runner, model, spaces, weather, hpxml_bldg, hpxml_header, schedules_file) + if hpxml_bldg.building_occupancy.number_of_residents == 0 + # Operational calculation w/ zero occupants, zero out energy use + return + end return if hpxml_bldg.ceiling_fans.size == 0 ceiling_fan = hpxml_bldg.ceiling_fans[0] @@ -1382,7 +1386,7 @@ def self.apply_setpoints(model, runner, weather, spaces, hpxml_bldg, hpxml_heade end if cooling_sch.nil? - clg_wd_setpoints, clg_we_setpoints = get_cooling_setpoints(hvac_control, has_ceiling_fan, year, weather, onoff_thermostat_ddb) + clg_wd_setpoints, clg_we_setpoints = get_cooling_setpoints(hpxml_bldg, hvac_control, has_ceiling_fan, year, weather, onoff_thermostat_ddb) else runner.registerWarning("Both '#{SchedulesFile::Columns[:CoolingSetpoint].name}' schedule file and cooling setpoint temperature provided; the latter will be ignored.") if !hvac_control.cooling_setpoint_temp.nil? end @@ -1511,13 +1515,14 @@ def self.get_heating_setpoints(hvac_control, year, offset_db) # TODO # + # @param hpxml_bldg [HPXML::Building] HPXML Building object representing an individual dwelling unit # @param [HPXML::HVACControl] The HPXML HVAC control of interest # @param has_ceiling_fan [TODO] TODO # @param year [Integer] the calendar year # @param weather [WeatherFile] Weather object containing EPW information # @param offset_db [Double] On-off thermostat deadband (F) # @return [TODO] TODO - def self.get_cooling_setpoints(hvac_control, has_ceiling_fan, year, weather, offset_db) + def self.get_cooling_setpoints(hpxml_bldg, hvac_control, has_ceiling_fan, year, weather, offset_db) num_days = Calendar.num_days_in_year(year) if hvac_control.weekday_cooling_setpoints.nil? || hvac_control.weekend_cooling_setpoints.nil? @@ -1543,8 +1548,9 @@ def self.get_cooling_setpoints(hvac_control, has_ceiling_fan, year, weather, off clg_we_setpoints = hvac_control.weekend_cooling_setpoints.split(',').map { |i| Float(i) } clg_we_setpoints = [clg_we_setpoints] * num_days end + # Apply cooling setpoint offset due to ceiling fan? - if has_ceiling_fan + if has_ceiling_fan && hpxml_bldg.building_occupancy.number_of_residents != 0 # If operational calculation w/ zero occupants, exclude ceiling fan setpoint adjustment clg_ceiling_fan_offset = hvac_control.ceiling_fan_cooling_setpoint_temp_offset if not clg_ceiling_fan_offset.nil? months = Defaults.get_ceiling_fan_months(weather) diff --git a/HPXMLtoOpenStudio/resources/misc_loads.rb b/HPXMLtoOpenStudio/resources/misc_loads.rb index 1b16344f16..e30ce386cc 100644 --- a/HPXMLtoOpenStudio/resources/misc_loads.rb +++ b/HPXMLtoOpenStudio/resources/misc_loads.rb @@ -211,11 +211,6 @@ def self.apply_fuel_load(runner, model, fuel_load, obj_name, spaces, schedules_f # @param schedules_file [SchedulesFile] SchedulesFile wrapper class instance of detailed schedule files # @return [nil] def self.apply_pools_and_permanent_spas(runner, model, spaces, hpxml_bldg, hpxml_header, schedules_file) - if hpxml_bldg.building_occupancy.number_of_residents == 0 - # Operational calculation w/ zero occupants, zero out energy use - return - end - (hpxml_bldg.pools + hpxml_bldg.permanent_spas).each do |pool_or_spa| next if pool_or_spa.type == HPXML::TypeNone diff --git a/HPXMLtoOpenStudio/tests/test_airflow.rb b/HPXMLtoOpenStudio/tests/test_airflow.rb index fa26004a0b..3937c41ad3 100644 --- a/HPXMLtoOpenStudio/tests/test_airflow.rb +++ b/HPXMLtoOpenStudio/tests/test_airflow.rb @@ -17,6 +17,7 @@ def setup def teardown File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_battery.rb b/HPXMLtoOpenStudio/tests/test_battery.rb index 0b8c52bd7e..549c4e5f21 100644 --- a/HPXMLtoOpenStudio/tests/test_battery.rb +++ b/HPXMLtoOpenStudio/tests/test_battery.rb @@ -9,6 +9,7 @@ class HPXMLtoOpenStudioBatteryTest < Minitest::Test def teardown + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_defaults.rb b/HPXMLtoOpenStudio/tests/test_defaults.rb index 6ad226279d..1b341429f9 100644 --- a/HPXMLtoOpenStudio/tests/test_defaults.rb +++ b/HPXMLtoOpenStudio/tests/test_defaults.rb @@ -29,6 +29,7 @@ def setup def teardown File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path FileUtils.rm_rf(@tmp_output_path) + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_enclosure.rb b/HPXMLtoOpenStudio/tests/test_enclosure.rb index d84a3e6041..9d805b7fbc 100644 --- a/HPXMLtoOpenStudio/tests/test_enclosure.rb +++ b/HPXMLtoOpenStudio/tests/test_enclosure.rb @@ -17,6 +17,7 @@ def setup def teardown File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_generator.rb b/HPXMLtoOpenStudio/tests/test_generator.rb index fe451d318c..b4ad564f3d 100644 --- a/HPXMLtoOpenStudio/tests/test_generator.rb +++ b/HPXMLtoOpenStudio/tests/test_generator.rb @@ -9,6 +9,7 @@ class HPXMLtoOpenStudioGeneratorTest < Minitest::Test def teardown + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb b/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb index 619be06570..79c31f885f 100644 --- a/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +++ b/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb @@ -9,6 +9,7 @@ class HPXMLtoOpenStudioHotWaterApplianceTest < Minitest::Test def teardown + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_hvac.rb b/HPXMLtoOpenStudio/tests/test_hvac.rb index 87ddb1f7dd..12b41f8837 100644 --- a/HPXMLtoOpenStudio/tests/test_hvac.rb +++ b/HPXMLtoOpenStudio/tests/test_hvac.rb @@ -1663,6 +1663,33 @@ def test_ceiling_fan assert_in_epsilon(cooling_setpoint_temp + ceiling_fan_cooling_setpoint_temp_offset, UnitConversions.convert(values[0], 'C', 'F'), 0.01) end + def test_operational_0_occupants + args_hash = {} + args_hash['hpxml_path'] = @tmp_hpxml_path + hpxml, hpxml_bldg = _create_hpxml('base-residents-0.xml') + hpxml_bldg.ceiling_fans.add(id: "CeilingFan#{hpxml_bldg.ceiling_fans.size + 1}") + hpxml_bldg.hvac_controls[0].ceiling_fan_cooling_setpoint_temp_offset = 2.0 + XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) + model, _hpxml, _hpxml_bldg = _test_measure(args_hash) + + # Get HPXML values + hvac_control = hpxml_bldg.hvac_controls[0] + cooling_setpoint_temp = hvac_control.cooling_setpoint_temp + + # Check ceiling fan months + assert_equal(1, model.getThermostatSetpointDualSetpoints.size) + thermostat = model.getThermostatSetpointDualSetpoints[0] + + cooling_schedule = thermostat.coolingSetpointTemperatureSchedule.get.to_ScheduleRuleset.get + assert_equal(1, cooling_schedule.scheduleRules.size) + + rule = cooling_schedule.scheduleRules[0] # year-round setpoints + day_schedule = rule.daySchedule + values = day_schedule.values + assert_equal(1, values.size) + assert_in_epsilon(cooling_setpoint_temp, UnitConversions.convert(values[0], 'C', 'F'), 0.01) + end + def _test_measure(args_hash) # create an instance of the measure measure = HPXMLtoOpenStudio.new diff --git a/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb b/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb index b04bbcb7f1..3460baeb1d 100644 --- a/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +++ b/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb @@ -20,10 +20,11 @@ def setup def teardown File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.json')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.json') + File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') - File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.json')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.json') end def test_hvac_configurations diff --git a/HPXMLtoOpenStudio/tests/test_lighting.rb b/HPXMLtoOpenStudio/tests/test_lighting.rb index 467f8acc41..042c4893ab 100644 --- a/HPXMLtoOpenStudio/tests/test_lighting.rb +++ b/HPXMLtoOpenStudio/tests/test_lighting.rb @@ -8,15 +8,19 @@ require_relative '../resources/util.rb' class HPXMLtoOpenStudioLightingTest < Minitest::Test + def setup + @root_path = File.absolute_path(File.join(File.dirname(__FILE__), '..', '..')) + @sample_files_path = File.join(@root_path, 'workflow', 'sample_files') + @tmp_hpxml_path = File.join(@sample_files_path, 'tmp.xml') + end + def teardown + File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end - def sample_files_dir - return File.join(File.dirname(__FILE__), '..', '..', 'workflow', 'sample_files') - end - def get_kwh_per_year(model, name) model.getLightss.each do |ltg| next unless ltg.name.to_s == name @@ -44,7 +48,7 @@ def get_kwh_per_year(model, name) def test_lighting args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check interior lighting @@ -56,7 +60,7 @@ def test_lighting def test_lighting_garage args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-enclosure-2stories-garage.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-enclosure-2stories-garage.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check interior lighting @@ -74,7 +78,7 @@ def test_exterior_holiday_lighting 'base-misc-defaults.xml', 'base-lighting-holiday.xml'].each do |hpxml_name| args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, hpxml_name)) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, hpxml_name)) model, _hpxml, hpxml_bldg = _test_measure(args_hash) if hpxml_name == 'base-lighting-holiday.xml' @@ -88,7 +92,7 @@ def test_exterior_holiday_lighting def test_lighting_kwh_per_year args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-lighting-kwh-per-year.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-lighting-kwh-per-year.xml')) model, _hpxml, hpxml_bldg = _test_measure(args_hash) # Check interior lighting @@ -104,7 +108,7 @@ def test_lighting_kwh_per_year def test_lighting_none args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-lighting-none.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-lighting-none.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check interior lighting @@ -120,14 +124,14 @@ def test_lighting_none def test_ceiling_fan # Efficiency args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-lighting-ceiling-fans.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-lighting-ceiling-fans.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) assert_in_delta(154, get_kwh_per_year(model, Constants::ObjectTypeCeilingFan), 1.0) # Label energy use args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-lighting-ceiling-fans-label-energy-use.xml')) + args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-lighting-ceiling-fans-label-energy-use.xml')) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) assert_in_delta(200, get_kwh_per_year(model, Constants::ObjectTypeCeilingFan), 1.0) @@ -135,7 +139,10 @@ def test_ceiling_fan def test_operational_0_occupants args_hash = {} - args_hash['hpxml_path'] = File.absolute_path(File.join(sample_files_dir, 'base-residents-0.xml')) + args_hash['hpxml_path'] = @tmp_hpxml_path + hpxml, hpxml_bldg = _create_hpxml('base-residents-0.xml') + hpxml_bldg.ceiling_fans.add(id: "CeilingFan#{hpxml_bldg.ceiling_fans.size + 1}") + XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path) model, _hpxml, _hpxml_bldg = _test_measure(args_hash) # Check interior lighting @@ -146,6 +153,9 @@ def test_operational_0_occupants # Check exterior lighting assert_equal(0.0, get_kwh_per_year(model, Constants::ObjectTypeLightingExterior)) + + # Check ceiling fan + assert_equal(0.0, get_kwh_per_year(model, Constants::ObjectTypeCeilingFan)) end def _test_measure(args_hash) @@ -185,4 +195,9 @@ def _test_measure(args_hash) return model, hpxml, hpxml.buildings[0] end + + def _create_hpxml(hpxml_name) + hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, hpxml_name)) + return hpxml, hpxml.buildings[0] + end end diff --git a/HPXMLtoOpenStudio/tests/test_location.rb b/HPXMLtoOpenStudio/tests/test_location.rb index 5fc9b1e138..f87bf27a26 100644 --- a/HPXMLtoOpenStudio/tests/test_location.rb +++ b/HPXMLtoOpenStudio/tests/test_location.rb @@ -9,6 +9,7 @@ class HPXMLtoOpenStudioLocationTest < Minitest::Test def teardown + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_miscloads.rb b/HPXMLtoOpenStudio/tests/test_miscloads.rb index 39c25df13d..8abb175436 100644 --- a/HPXMLtoOpenStudio/tests/test_miscloads.rb +++ b/HPXMLtoOpenStudio/tests/test_miscloads.rb @@ -16,6 +16,7 @@ def setup def teardown File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end @@ -263,13 +264,13 @@ def test_operational_0_occupants # Check permanent spa pump kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPermanentSpaPump) - assert_equal(0, kwh_yr) - assert_equal(0, therm_yr) + refute_equal(0, kwh_yr) + refute_equal(0, therm_yr) # Check permanent spa heater kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPermanentSpaHeater) - assert_equal(0, kwh_yr) - assert_equal(0, therm_yr) + refute_equal(0, kwh_yr) + refute_equal(0, therm_yr) # Check grill kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscGrill) diff --git a/HPXMLtoOpenStudio/tests/test_pv.rb b/HPXMLtoOpenStudio/tests/test_pv.rb index 55b6ac82d3..e79f784b6b 100644 --- a/HPXMLtoOpenStudio/tests/test_pv.rb +++ b/HPXMLtoOpenStudio/tests/test_pv.rb @@ -9,6 +9,7 @@ class HPXMLtoOpenStudioPVTest < Minitest::Test def teardown + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_schedules.rb b/HPXMLtoOpenStudio/tests/test_schedules.rb index aab2621538..b8314a470b 100644 --- a/HPXMLtoOpenStudio/tests/test_schedules.rb +++ b/HPXMLtoOpenStudio/tests/test_schedules.rb @@ -23,6 +23,7 @@ def setup def teardown File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path File.delete(@tmp_schedule_file_path) if File.exist? @tmp_schedule_file_path + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_simcontrols.rb b/HPXMLtoOpenStudio/tests/test_simcontrols.rb index 7713b171a4..d8ef769f49 100644 --- a/HPXMLtoOpenStudio/tests/test_simcontrols.rb +++ b/HPXMLtoOpenStudio/tests/test_simcontrols.rb @@ -9,6 +9,7 @@ class HPXMLtoOpenStudioSimControlsTest < Minitest::Test def teardown + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_validation.rb b/HPXMLtoOpenStudio/tests/test_validation.rb index 21f4bf08e0..1f9f807f1d 100644 --- a/HPXMLtoOpenStudio/tests/test_validation.rb +++ b/HPXMLtoOpenStudio/tests/test_validation.rb @@ -30,6 +30,7 @@ def teardown File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path File.delete(@tmp_csv_path) if File.exist? @tmp_csv_path FileUtils.rm_rf(@tmp_output_path) + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_water_heater.rb b/HPXMLtoOpenStudio/tests/test_water_heater.rb index 50677c78d3..734e3e410f 100644 --- a/HPXMLtoOpenStudio/tests/test_water_heater.rb +++ b/HPXMLtoOpenStudio/tests/test_water_heater.rb @@ -8,6 +8,7 @@ class HPXMLtoOpenStudioWaterHeaterTest < Minitest::Test def teardown + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end diff --git a/HPXMLtoOpenStudio/tests/test_weather.rb b/HPXMLtoOpenStudio/tests/test_weather.rb index 712354c381..1b70c0e136 100644 --- a/HPXMLtoOpenStudio/tests/test_weather.rb +++ b/HPXMLtoOpenStudio/tests/test_weather.rb @@ -18,6 +18,7 @@ class HPXMLtoOpenStudioWeatherTest < Minitest::Test def teardown + File.delete(File.join(File.dirname(__FILE__), 'in.schedules.csv')) if File.exist? File.join(File.dirname(__FILE__), 'in.schedules.csv') File.delete(File.join(File.dirname(__FILE__), 'results_annual.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_annual.csv') File.delete(File.join(File.dirname(__FILE__), 'results_design_load_details.csv')) if File.exist? File.join(File.dirname(__FILE__), 'results_design_load_details.csv') end From 934ddf42a9312b80fb59f8502a34ef32f5c2b1a0 Mon Sep 17 00:00:00 2001 From: Scott Horowitz Date: Thu, 19 Dec 2024 13:36:30 -0700 Subject: [PATCH 6/6] Fix test. --- HPXMLtoOpenStudio/measure.xml | 6 +++--- HPXMLtoOpenStudio/tests/test_miscloads.rb | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 05e680e9c3..92e8bf0c7f 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - 0bff6a77-c10a-4a70-bb9b-4b1efdb32682 - 2024-12-19T18:29:02Z + e40bba9f-1d2a-4724-8e09-2e9fe9c75e87 + 2024-12-19T20:14:45Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -711,7 +711,7 @@ test_miscloads.rb rb test - CBD61753 + 4E0D3190 test_pv.rb diff --git a/HPXMLtoOpenStudio/tests/test_miscloads.rb b/HPXMLtoOpenStudio/tests/test_miscloads.rb index 8abb175436..65fd7d012b 100644 --- a/HPXMLtoOpenStudio/tests/test_miscloads.rb +++ b/HPXMLtoOpenStudio/tests/test_miscloads.rb @@ -254,23 +254,23 @@ def test_operational_0_occupants # Check pool pump kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPoolPump) - assert_equal(0, kwh_yr) + refute_equal(0, kwh_yr) assert_equal(0, therm_yr) # Check pool heater kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPoolHeater) assert_equal(0, kwh_yr) - assert_equal(0, therm_yr) + refute_equal(0, therm_yr) # Check permanent spa pump kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPermanentSpaPump) refute_equal(0, kwh_yr) - refute_equal(0, therm_yr) + assert_equal(0, therm_yr) # Check permanent spa heater kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscPermanentSpaHeater) refute_equal(0, kwh_yr) - refute_equal(0, therm_yr) + assert_equal(0, therm_yr) # Check grill kwh_yr, therm_yr = get_kwh_therm_per_year(model, Constants::ObjectTypeMiscGrill)