Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions HPXMLtoOpenStudio/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>hpxm_lto_openstudio</name>
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
<version_id>fdc58219-1784-49c0-99e5-eacd493166c0</version_id>
<version_modified>2026-02-04T15:42:28Z</version_modified>
<version_id>99bc2812-bd0f-4c78-b70b-53de0c3e6825</version_id>
<version_modified>2026-02-05T20:24:35Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLtoOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -480,7 +480,7 @@
<filename>output.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>9AC90250</checksum>
<checksum>27CD133C</checksum>
</file>
<file>
<filename>psychrometrics.rb</filename>
Expand Down
9 changes: 7 additions & 2 deletions HPXMLtoOpenStudio/resources/output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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']
Expand Down
31 changes: 6 additions & 25 deletions ReportSimulationOutput/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -397,19 +397,14 @@ 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]
resilience_frequency = EPlus::TimeseriesFrequencyTimestep
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)
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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)
Expand All @@ -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
Comment on lines +1479 to +1480
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought about moving this to a custom meter too, but these are annual outputs and only used here, so not a big benefit. (And if we moved them, we'd also have to move the logic to determine when these meters are available.)

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)}).")
Expand Down
6 changes: 3 additions & 3 deletions ReportSimulationOutput/measure.xml
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<schema_version>3.1</schema_version>
<name>report_simulation_output</name>
<uid>df9d170c-c21a-4130-866d-0d46b06073fd</uid>
<version_id>4d7c636a-69a4-4de1-a7d1-b5c9200c3486</version_id>
<version_modified>2026-01-29T23:10:47Z</version_modified>
<version_id>d76d957c-7907-4943-8c57-e95fddc1327e</version_id>
<version_modified>2026-02-05T20:24:39Z</version_modified>
<xml_checksum>9BF1E6AC</xml_checksum>
<class_name>ReportSimulationOutput</class_name>
<display_name>HPXML Simulation Output Report</display_name>
Expand Down Expand Up @@ -1991,7 +1991,7 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>583545A5</checksum>
<checksum>583EF2A9</checksum>
</file>
<file>
<filename>test_report_sim_output.rb</filename>
Expand Down