Skip to content

Commit

Permalink
First pass on new SupplementalFanRunsWithAirHandlerFan input for CFIS…
Browse files Browse the repository at this point in the history
… systems.
  • Loading branch information
shorowit committed Oct 22, 2024
1 parent 9332bad commit 1b54249
Show file tree
Hide file tree
Showing 11 changed files with 681 additions and 56 deletions.
2 changes: 1 addition & 1 deletion HPXMLtoOpenStudio/measure.rb
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ def run(model, runner, user_arguments)
Outputs.apply_ems_programs(model, hpxml_osm_map, hpxml.header, args[:add_component_loads])
Outputs.apply_output_file_controls(model, args[:debug])
Outputs.apply_additional_properties(model, hpxml, hpxml_osm_map, args[:hpxml_path], args[:building_id], args[:hpxml_defaults_path])
# Outputs.apply_ems_debug_output(model) # Uncomment to debug EMS
Outputs.apply_ems_debug_output(model) # Uncomment to debug EMS

# Write output files
Outputs.write_debug_files(runner, model, args[:debug], args[:output_dir], epw_path)
Expand Down
16 changes: 8 additions & 8 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>aab4ee31-48b7-4f7a-bfc0-1d8edf16961d</version_id>
<version_modified>2024-10-22T03:59:34Z</version_modified>
<version_id>4599ec47-df00-4af8-920a-2a4c460640d9</version_id>
<version_modified>2024-10-22T18:46:21Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLtoOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -183,13 +183,13 @@
<filename>measure.rb</filename>
<filetype>rb</filetype>
<usage_type>script</usage_type>
<checksum>E1E63AE7</checksum>
<checksum>33FF636A</checksum>
</file>
<file>
<filename>airflow.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>D2A99996</checksum>
<checksum>006218CD</checksum>
</file>
<file>
<filename>battery.rb</filename>
Expand Down Expand Up @@ -327,7 +327,7 @@
<filename>defaults.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>5B6D3CB2</checksum>
<checksum>E52E98C6</checksum>
</file>
<file>
<filename>energyplus.rb</filename>
Expand Down Expand Up @@ -357,7 +357,7 @@
<filename>hpxml.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>E862E878</checksum>
<checksum>656CF61F</checksum>
</file>
<file>
<filename>hpxml_schema/HPXML.xsd</filename>
Expand All @@ -375,7 +375,7 @@
<filename>hpxml_schematron/EPvalidator.xml</filename>
<filetype>xml</filetype>
<usage_type>resource</usage_type>
<checksum>009BEB48</checksum>
<checksum>DD7BB2F9</checksum>
</file>
<file>
<filename>hpxml_schematron/iso-schematron.xsd</filename>
Expand Down Expand Up @@ -663,7 +663,7 @@
<filename>test_defaults.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>9D489184</checksum>
<checksum>77AFEE2C</checksum>
</file>
<file>
<filename>test_enclosure.rb</filename>
Expand Down
21 changes: 15 additions & 6 deletions HPXMLtoOpenStudio/resources/airflow.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1990,6 +1990,9 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a
infil_program.addLine("Set #{f_extra_open_damper_var.name} = 0")
infil_program.addLine("Set has_additional_runtime = #{vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeNone ? 0 : 1}")
infil_program.addLine("Set has_outdoor_air_control = #{vent_mech.cfis_has_outdoor_air_control ? 1 : 0}")
if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan
infil_program.addLine("Set suppl_fan_w = #{vent_mech.cfis_supplemental_fan.unit_fan_power}") # W
end

infil_program.addLine("If #{t_sum_open_damper_var.name} < t_min_hr_open") # Check whether we've met the minimum hourly runtime
infil_program.addLine(" Set t_damper_open = 60 - (t_min_hr_open - #{t_sum_open_damper_var.name})") # Minute of the hour at which the damper must be opened
Expand All @@ -2015,7 +2018,6 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a
else
infil_program.addLine(' Set suppl_f = 0.0')
end
infil_program.addLine(" Set suppl_fan_w = #{vent_mech.cfis_supplemental_fan.unit_fan_power}") # W
infil_program.addLine(" Set #{cfis_suppl_fan_actuator.name} = #{cfis_suppl_fan_actuator.name} + suppl_fan_w * suppl_f")
if vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeSupply
infil_program.addLine(' Set QWHV_cfis_suppl_sup = QWHV_cfis_suppl_sup + (suppl_f * suppl_Q_oa)')
Expand All @@ -2031,14 +2033,21 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a
infil_program.addLine(' Set f_total_open_damper = open_damper_runtime / (ZoneTimeStep * 60)') # Fraction of the timestep that the damper is open
infil_program.addLine(" Set #{t_sum_open_damper_var.name} = #{t_sum_open_damper_var.name} + open_damper_runtime")
infil_program.addLine(' EndIf')
if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan
infil_program.addLine(" Set f_total_open_damper = @Max (f_total_open_damper - #{f_extra_open_damper_var.name}) 0.0")
end
infil_program.addLine(" Set f_hvac_open_damper = @Max (f_total_open_damper - #{f_extra_open_damper_var.name}) 0.0") # Fraction of the timestep that the damper is open and the HVAC system is running
infil_program.addLine('EndIf')
infil_program.addLine('If has_outdoor_air_control == 0')
infil_program.addLine(' Set f_total_open_damper = @Max f_total_open_damper fan_rtf_hvac') # Outdoor air is introduced for at least the entire time the HVAC system is running
infil_program.addLine(' Set f_hvac_open_damper = @Max f_hvac_open_damper fan_rtf_hvac') # Outdoor air is introduced for at least the entire time the HVAC system is running
infil_program.addLine('EndIf')
infil_program.addLine('Set QWHV_cfis_sup = QWHV_cfis_sup + (f_total_open_damper * Q_duct_oa)')
infil_program.addLine('Set QWHV_cfis_sup = QWHV_cfis_sup + (f_hvac_open_damper * Q_duct_oa)')
next unless vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan && vent_mech.cfis_supplemental_fan_runs_with_air_handler_fan

# Also run supplemental fan when damper is open and HVAC system is running
infil_program.addLine("Set #{cfis_suppl_fan_actuator.name} = #{cfis_suppl_fan_actuator.name} + (suppl_fan_w * f_hvac_open_damper)")
if vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeSupply
infil_program.addLine('Set QWHV_cfis_suppl_sup = QWHV_cfis_suppl_sup + (f_hvac_open_damper * suppl_Q_oa)')
elsif vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeExhaust
infil_program.addLine('Set QWHV_cfis_suppl_exh = QWHV_cfis_suppl_exh + (f_hvac_open_damper * suppl_Q_oa)')
end
end
end

Expand Down
4 changes: 4 additions & 0 deletions HPXMLtoOpenStudio/resources/defaults.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2755,6 +2755,10 @@ def self.apply_ventilation_fans(hpxml_bldg, weather, eri_version)
vent_fan.cfis_vent_mode_airflow_fraction = 1.0
vent_fan.cfis_vent_mode_airflow_fraction_isdefaulted = true
end
if vent_fan.cfis_supplemental_fan_runs_with_air_handler_fan.nil? && (vent_fan.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan)
vent_fan.cfis_supplemental_fan_runs_with_air_handler_fan = false
vent_fan.cfis_supplemental_fan_runs_with_air_handler_fan_isdefaulted = true
end
end

# Default kitchen fan
Expand Down
75 changes: 39 additions & 36 deletions HPXMLtoOpenStudio/resources/hpxml.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7993,41 +7993,42 @@ def from_doc(building)

# Object for /HPXML/Building/BuildingDetails/Systems/MechanicalVentilation/VentilationFans/VentilationFan.
class VentilationFan < BaseElement
ATTRS = [:id, # [String] SystemIdentifier/@id
:count, # [Integer] Count
:fan_type, # [String] FanType (HPXML::MechVentTypeXXX)
:cfis_has_outdoor_air_control, # [Boolean] CFISControls/HasOutdoorAirControl
:cfis_addtl_runtime_operating_mode, # [String] CFISControls/AdditionalRuntimeOperatingMode (HPXML::CFISModeXXX)
:cfis_supplemental_fan_idref, # [String] CFISControls/SupplementalFan/@idref
:rated_flow_rate, # [Double] RatedFlowRate (cfm)
:calculated_flow_rate, # [Double] CalculatedFlowRate (cfm)
:tested_flow_rate, # [Double] TestedFlowRate (cfm)
:hours_in_operation, # [Double] HoursInOperation (hrs/day)
:delivered_ventilation, # [Double] DeliveredVentilation (cfm)
:fan_location, # [String] FanLocation (HPXML::LocationXXX)
:used_for_local_ventilation, # [Boolean] UsedForLocalVentilation
:used_for_whole_building_ventilation, # [Boolean] UsedForWholeBuildingVentilation
:used_for_seasonal_cooling_load_reduction, # [Boolean] UsedForSeasonalCoolingLoadReduction
:used_for_garage_ventilation, # [Boolean] UsedForGarageVentilation
:is_shared_system, # [Boolean] IsSharedSystem
:fraction_recirculation, # [Double] FractionRecirculation (frac)
:total_recovery_efficiency, # [Double] TotalRecoveryEfficiency (frac)
:sensible_recovery_efficiency, # [Double] SensibleRecoveryEfficiency (frac)
:total_recovery_efficiency_adjusted, # [Double] AdjustedTotalRecoveryEfficiency (frac)
:sensible_recovery_efficiency_adjusted, # [Double] AdjustedSensibleRecoveryEfficiency (frac)
:fan_power, # [Double] FanPower (W)
:distribution_system_idref, # [String] AttachedToHVACDistributionSystem/@idref
:start_hour, # [Integer] extension/StartHour
:in_unit_flow_rate, # [Double] extension/InUnitFlowRate (cfm)
:preheating_fuel, # [String] extension/PreHeating/Fuel (HPXML::FuelTypeXXX)
:preheating_efficiency_cop, # [Double] extension/PreHeating/AnnualHeatingEfficiency[Units="COP"]/Value (W/W)
:preheating_fraction_load_served, # [Double] extension/PreHeating/FractionVentilationHeatLoadServed (frac)
:precooling_fuel, # [String] extension/PreCooling/Fuel (HPXML::FuelTypeXXX)
:precooling_efficiency_cop, # [Double] extension/PreCooling/AnnualCoolingEfficiency[Units="COP"]/Value (W/W)
:precooling_fraction_load_served, # [Double] extension/PreCooling/FractionVentilationCoolLoadServed (frac)
:flow_rate_not_tested, # [Boolean] extension/FlowRateNotTested
:fan_power_defaulted, # [Boolean] extension/FanPowerDefaulted
:cfis_vent_mode_airflow_fraction] # [Double] extension/VentilationOnlyModeAirflowFraction (frac)
ATTRS = [:id, # [String] SystemIdentifier/@id
:count, # [Integer] Count
:fan_type, # [String] FanType (HPXML::MechVentTypeXXX)
:cfis_has_outdoor_air_control, # [Boolean] CFISControls/HasOutdoorAirControl
:cfis_addtl_runtime_operating_mode, # [String] CFISControls/AdditionalRuntimeOperatingMode (HPXML::CFISModeXXX)
:cfis_supplemental_fan_idref, # [String] CFISControls/SupplementalFan/@idref
:cfis_supplemental_fan_runs_with_air_handler_fan, # [Boolean] CFISControls/extension/SupplementalFanRunsWithAirHandlerFan
:rated_flow_rate, # [Double] RatedFlowRate (cfm)
:calculated_flow_rate, # [Double] CalculatedFlowRate (cfm)
:tested_flow_rate, # [Double] TestedFlowRate (cfm)
:hours_in_operation, # [Double] HoursInOperation (hrs/day)
:delivered_ventilation, # [Double] DeliveredVentilation (cfm)
:fan_location, # [String] FanLocation (HPXML::LocationXXX)
:used_for_local_ventilation, # [Boolean] UsedForLocalVentilation
:used_for_whole_building_ventilation, # [Boolean] UsedForWholeBuildingVentilation
:used_for_seasonal_cooling_load_reduction, # [Boolean] UsedForSeasonalCoolingLoadReduction
:used_for_garage_ventilation, # [Boolean] UsedForGarageVentilation
:is_shared_system, # [Boolean] IsSharedSystem
:fraction_recirculation, # [Double] FractionRecirculation (frac)
:total_recovery_efficiency, # [Double] TotalRecoveryEfficiency (frac)
:sensible_recovery_efficiency, # [Double] SensibleRecoveryEfficiency (frac)
:total_recovery_efficiency_adjusted, # [Double] AdjustedTotalRecoveryEfficiency (frac)
:sensible_recovery_efficiency_adjusted, # [Double] AdjustedSensibleRecoveryEfficiency (frac)
:fan_power, # [Double] FanPower (W)
:distribution_system_idref, # [String] AttachedToHVACDistributionSystem/@idref
:start_hour, # [Integer] extension/StartHour
:in_unit_flow_rate, # [Double] extension/InUnitFlowRate (cfm)
:preheating_fuel, # [String] extension/PreHeating/Fuel (HPXML::FuelTypeXXX)
:preheating_efficiency_cop, # [Double] extension/PreHeating/AnnualHeatingEfficiency[Units="COP"]/Value (W/W)
:preheating_fraction_load_served, # [Double] extension/PreHeating/FractionVentilationHeatLoadServed (frac)
:precooling_fuel, # [String] extension/PreCooling/Fuel (HPXML::FuelTypeXXX)
:precooling_efficiency_cop, # [Double] extension/PreCooling/AnnualCoolingEfficiency[Units="COP"]/Value (W/W)
:precooling_fraction_load_served, # [Double] extension/PreCooling/FractionVentilationCoolLoadServed (frac)
:flow_rate_not_tested, # [Boolean] extension/FlowRateNotTested
:fan_power_defaulted, # [Boolean] extension/FanPowerDefaulted
:cfis_vent_mode_airflow_fraction] # [Double] extension/VentilationOnlyModeAirflowFraction (frac)
attr_accessor(*ATTRS)

# Returns the HVAC distribution system for the ventilation fan.
Expand Down Expand Up @@ -8244,14 +8245,15 @@ def to_doc(building)
XMLHelper.add_attribute(sys_id, 'id', @id)
XMLHelper.add_element(ventilation_fan, 'Count', @count, :integer, @count_isdefaulted) unless @count.nil?
XMLHelper.add_element(ventilation_fan, 'FanType', @fan_type, :string) unless @fan_type.nil?
if (not @cfis_addtl_runtime_operating_mode.nil?) || (not @cfis_supplemental_fan_idref.nil?) || (not @cfis_has_outdoor_air_control.nil?)
if (not @cfis_addtl_runtime_operating_mode.nil?) || (not @cfis_supplemental_fan_idref.nil?) || (not @cfis_has_outdoor_air_control.nil?) || (not @cfis_supplemental_fan_runs_with_air_handler_fan.nil?)
cfis_controls = XMLHelper.add_element(ventilation_fan, 'CFISControls')
XMLHelper.add_element(cfis_controls, 'HasOutdoorAirControl', @cfis_has_outdoor_air_control, :boolean, @cfis_has_outdoor_air_control_isdefaulted) unless @cfis_has_outdoor_air_control.nil?
XMLHelper.add_element(cfis_controls, 'AdditionalRuntimeOperatingMode', @cfis_addtl_runtime_operating_mode, :string, @cfis_addtl_runtime_operating_mode_isdefaulted) unless @cfis_addtl_runtime_operating_mode.nil?
if not @cfis_supplemental_fan_idref.nil?
supplemental_fan = XMLHelper.add_element(cfis_controls, 'SupplementalFan')
XMLHelper.add_attribute(supplemental_fan, 'idref', @cfis_supplemental_fan_idref)
end
XMLHelper.add_extension(cfis_controls, 'SupplementalFanRunsWithAirHandlerFan', @cfis_supplemental_fan_runs_with_air_handler_fan, :boolean, @cfis_supplemental_fan_runs_with_air_handler_fan_isdefaulted) unless @cfis_supplemental_fan_runs_with_air_handler_fan.nil?
end
XMLHelper.add_element(ventilation_fan, 'RatedFlowRate', @rated_flow_rate, :float, @rated_flow_rate_isdefaulted) unless @rated_flow_rate.nil?
XMLHelper.add_element(ventilation_fan, 'CalculatedFlowRate', @calculated_flow_rate, :float, @calculated_flow_rate_isdefaulted) unless @calculated_flow_rate.nil?
Expand Down Expand Up @@ -8310,6 +8312,7 @@ def from_doc(ventilation_fan)
@cfis_has_outdoor_air_control = XMLHelper.get_value(ventilation_fan, 'CFISControls/HasOutdoorAirControl', :boolean)
@cfis_addtl_runtime_operating_mode = XMLHelper.get_value(ventilation_fan, 'CFISControls/AdditionalRuntimeOperatingMode', :string)
@cfis_supplemental_fan_idref = HPXML::get_idref(XMLHelper.get_element(ventilation_fan, 'CFISControls/SupplementalFan'))
@cfis_supplemental_fan_runs_with_air_handler_fan = XMLHelper.get_value(ventilation_fan, 'CFISControls/extension/SupplementalFanRunsWithAirHandlerFan', :boolean)
@rated_flow_rate = XMLHelper.get_value(ventilation_fan, 'RatedFlowRate', :float)
@calculated_flow_rate = XMLHelper.get_value(ventilation_fan, 'CalculatedFlowRate', :float)
@tested_flow_rate = XMLHelper.get_value(ventilation_fan, 'TestedFlowRate', :float)
Expand Down
Loading

0 comments on commit 1b54249

Please sign in to comment.