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