diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml index 69d8e4e9b8..a12b3f68a4 100644 --- a/HPXMLtoOpenStudio/measure.xml +++ b/HPXMLtoOpenStudio/measure.xml @@ -3,8 +3,8 @@ 3.1 hpxm_lto_openstudio b1543b30-9465-45ff-ba04-1d1f85e763bc - fdc58219-1784-49c0-99e5-eacd493166c0 - 2026-02-04T15:42:28Z + 99bc2812-bd0f-4c78-b70b-53de0c3e6825 + 2026-02-05T20:24:35Z D8922A73 HPXMLtoOpenStudio HPXML to OpenStudio Translator @@ -480,7 +480,7 @@ output.rb rb resource - 9AC90250 + 27CD133C psychrometrics.rb diff --git a/HPXMLtoOpenStudio/resources/output.rb b/HPXMLtoOpenStudio/resources/output.rb index 627a0ea3c2..ba7ff3ebd9 100644 --- a/HPXMLtoOpenStudio/resources/output.rb +++ b/HPXMLtoOpenStudio/resources/output.rb @@ -5,6 +5,7 @@ module Outputs MeterCustomElectricityTotal = 'Electricity:Total' MeterCustomElectricityNet = 'Electricity:Net' MeterCustomElectricityPV = 'Electricity:PV' + MeterCustomElectricityCritical = 'Electricity:Critical' # Add EMS programs for output reporting. In the case where a whole SFA/MF building is # being simulated, these programs are added to the whole building (merged) model, not @@ -1451,10 +1452,12 @@ def self.create_custom_meters(model) # - Total Electricity (Electricity:Facility plus EV charging, batteries, generators) # - Net Electricity (above plus PV) # - PV Electricity + # - Critical Electricity (Electricity:Facility plus PV, generators) total_key_vars = [] net_key_vars = [] pv_key_vars = [] + gen_key_vars = [] model.getElectricLoadCenterDistributions.each do |elcd| # Batteries & EV charging output variables if elcd.electricalStorage.is_initialized @@ -1486,12 +1489,14 @@ def self.create_custom_meters(model) net_key_vars << ['', 'Cogeneration:ElectricityProduced'] total_key_vars << net_key_vars[-1] + gen_key_vars << net_key_vars[-1] end end - # Create Total/Net meters + # Create Total/Net/Critical meters { MeterCustomElectricityTotal => total_key_vars, - MeterCustomElectricityNet => net_key_vars }.each do |meter_name, key_vars| + MeterCustomElectricityNet => net_key_vars, + MeterCustomElectricityCritical => pv_key_vars + gen_key_vars }.each do |meter_name, key_vars| if key_vars.empty? # Avoid OpenStudio warnings if nothing to decrement key_vars << ['', 'Electricity:Facility'] diff --git a/ReportSimulationOutput/measure.rb b/ReportSimulationOutput/measure.rb index 79602b70b3..84eb7df25b 100644 --- a/ReportSimulationOutput/measure.rb +++ b/ReportSimulationOutput/measure.rb @@ -397,9 +397,6 @@ def modelOutputRequests(model, runner, user_arguments) end if has_electricity_storage Model.add_output_meter(model, meter_name: 'ElectricStorage:ElectricityProduced', reporting_frequency: 'runperiod') # Used for error checking - if args[:include_timeseries_fuel_consumptions] - Model.add_output_meter(model, meter_name: 'ElectricStorage:ElectricityProduced', reporting_frequency: args[:timeseries_frequency]) - end # Resilience if args[:include_annual_resilience] || args[:include_timeseries_resilience] @@ -407,9 +404,7 @@ def modelOutputRequests(model, runner, user_arguments) if args[:timeseries_frequency] != EPlus::TimeseriesFrequencyTimestep resilience_frequency = EPlus::TimeseriesFrequencyHourly end - Model.add_output_meter(model, meter_name: 'Electricity:Facility', reporting_frequency: resilience_frequency) - Model.add_output_meter(model, meter_name: 'ElectricityProduced:Facility', reporting_frequency: resilience_frequency) - Model.add_output_meter(model, meter_name: 'ElectricStorage:ElectricityProduced', reporting_frequency: resilience_frequency) + Model.add_output_meter(model, meter_name: Outputs::MeterCustomElectricityCritical, reporting_frequency: resilience_frequency) @resilience.values.each do |resilience| resilience.variables.each do |_sys_id, varkey, var| Model.add_output_variable(model, key_value: varkey, variable_name: var, reporting_frequency: resilience_frequency) @@ -1081,11 +1076,8 @@ def get_outputs(runner, args) batt_kwh = elcs.additionalProperties.getFeatureAsDouble('UsableCapacity_kWh').get batt_soc_kwh = batt_soc.map { |soc| soc - min_soc }.map { |soc| soc * batt_kwh } - elec_prod = get_report_meter_data_timeseries(['ElectricityProduced:Facility'], UnitConversions.convert(1.0, 'J', 'kWh'), 0, resilience_frequency) - elec_stor = get_report_meter_data_timeseries(['ElectricStorage:ElectricityProduced'], UnitConversions.convert(1.0, 'J', 'kWh'), 0, resilience_frequency) - elec_prod = elec_prod.zip(elec_stor).map { |x, y| -1 * (x - y) } - elec = get_report_meter_data_timeseries(['Electricity:Facility'], UnitConversions.convert(1.0, 'J', 'kWh'), 0, resilience_frequency) - crit_load = elec.zip(elec_prod).map { |x, y| x + y } + + crit_load = get_report_meter_data_timeseries([Outputs::MeterCustomElectricityCritical.upcase], UnitConversions.convert(1.0, 'J', 'kWh'), 0, resilience_frequency) resilience_timeseries = [] n_timesteps = crit_load.size @@ -1471,19 +1463,6 @@ def get_sim_hours_of_year(year) def check_for_errors(runner) tol = 0.1 # 0.1% - # ElectricityProduced:Facility contains: - # - Generator Produced DC Electricity Energy - # - Inverter Conversion Loss Decrement Energy - # - Electric Storage Production Decrement Energy - # - Electric Storage Discharge Energy - # - Converter Electricity Loss Decrement Energy (should always be zero since efficiency=1.0) - # ElectricStorage:ElectricityProduced contains: - # - Electric Storage Production Decrement Energy - # - Electric Storage Discharge Energy - # So, we need to subtract ElectricStorage:ElectricityProduced from ElectricityProduced:Facility - meter_elec_produced = -1 * get_report_meter_data_annual(['ElectricityProduced:Facility']) - meter_elec_produced += get_report_meter_data_annual(['ElectricStorage:ElectricityProduced']) - # Check if simulation successful all_total = @fuels.values.map { |x| x.annual_output.to_f }.sum(0.0) total_fraction_cool_load_served = @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.total_fraction_cool_load_served }.sum(0.0) @@ -1497,7 +1476,9 @@ def check_for_errors(runner) end # Check sum of electricity produced end use outputs match total output from meter - sum_elec_prod_annual = @end_uses.select { |k, eu| k[0] == FT::Elec && eu.is_negative }.map { |_k, eu| eu.annual_output.to_f }.sum(0.0) # Negative value + meter_elec_produced = get_report_meter_data_annual(['ElectricityProduced:Facility']) + meter_elec_produced -= get_report_meter_data_annual(['ElectricStorage:ElectricityProduced']) # ElectricityProduced:Facility contains ElectricStorage:ElectricityProduced, so we have to subtract it + sum_elec_prod_annual = @end_uses.select { |k, eu| k[0] == FT::Elec && eu.is_negative }.map { |_k, eu| eu.annual_output.to_f }.sum(0.0).abs # Positive value avg_value = (sum_elec_prod_annual + meter_elec_produced) / 2.0 if (sum_elec_prod_annual - meter_elec_produced).abs / avg_value > tol runner.registerError("#{FT::Elec} produced category end uses (#{sum_elec_prod_annual.round(3)}) do not sum to total (#{meter_elec_produced.round(3)}).") diff --git a/ReportSimulationOutput/measure.xml b/ReportSimulationOutput/measure.xml index bf2a4c6d1f..52804c61aa 100644 --- a/ReportSimulationOutput/measure.xml +++ b/ReportSimulationOutput/measure.xml @@ -3,8 +3,8 @@ 3.1 report_simulation_output df9d170c-c21a-4130-866d-0d46b06073fd - 4d7c636a-69a4-4de1-a7d1-b5c9200c3486 - 2026-01-29T23:10:47Z + d76d957c-7907-4943-8c57-e95fddc1327e + 2026-02-05T20:24:39Z 9BF1E6AC ReportSimulationOutput HPXML Simulation Output Report @@ -1991,7 +1991,7 @@ measure.rb rb script - 583545A5 + 583EF2A9 test_report_sim_output.rb