diff --git a/Changelog.md b/Changelog.md
index 499070bb67..f20fbcabea 100644
--- a/Changelog.md
+++ b/Changelog.md
@@ -17,9 +17,10 @@ __New Features__
- Updates relationship between number of bedrooms and number of occupants to use RECS 2020 instead of RECS 2015.
- Allows optional `HeatingCapacity` and `BackupHeatingCapacity` inputs for heat pump water heaters (HPWHs).
- Central Fan Integrated Supply (CFIS) mechanical ventilation enhancements:
- - CFIS systems without automatic flow control of outdoor air (`CFISControls/HasOutdoorAirControl=false`).
- - CFIS systems with no strategy to meet remainder of ventilation target (`CFISControls/AdditionalRuntimeOperatingMode="none"`).
- - CFIS systems with supplemental fans that run simultaneously with the air handler (`CFISControls/extension/SupplementalFanRunsWithAirHandlerFan=true`).
+ - Allows CFIS systems without automatic flow control of outdoor air (`CFISControls/HasOutdoorAirControl=false`).
+ - Allows CFIS systems with no strategy to meet remainder of ventilation target (`CFISControls/AdditionalRuntimeOperatingMode="none"`).
+ - Allows CFIS systems with supplemental fans that run simultaneously with the air handler (`CFISControls/extension/SupplementalFanRunsWithAirHandlerFan=true`).
+ - Allows CFIS systems with timer control, in which ventilation operation occurs at a fixed interval (`CFISControls/extension/ControlType="timer"`).
- HVAC Manual J design load and sizing calculations:
- Adds optional `DistributionSystemType/AirDistribution/extension/ManualJInputs/BlowerFanHeatBtuh` input.
- Adds optional `DistributionSystemType/HydronicDistribution/extension/ManualJInputs/HotWaterPipingBtuh` input.
diff --git a/HPXMLtoOpenStudio/measure.xml b/HPXMLtoOpenStudio/measure.xml
index 2f9ffeebaf..2d7f57822c 100644
--- a/HPXMLtoOpenStudio/measure.xml
+++ b/HPXMLtoOpenStudio/measure.xml
@@ -3,8 +3,8 @@
3.1
hpxm_lto_openstudio
b1543b30-9465-45ff-ba04-1d1f85e763bc
- 6f307da4-b354-4c31-897f-de2161a9de82
- 2024-10-22T21:49:52Z
+ a34fa4e4-deee-4e59-8f0b-8c1a2c574cdc
+ 2024-10-23T18:46:26Z
D8922A73
HPXMLtoOpenStudio
HPXML to OpenStudio Translator
@@ -189,7 +189,7 @@
airflow.rb
rb
resource
- FFA79541
+ F2AD4FE1
battery.rb
@@ -327,7 +327,7 @@
defaults.rb
rb
resource
- E52E98C6
+ 0329B068
energyplus.rb
@@ -357,7 +357,7 @@
hpxml.rb
rb
resource
- 656CF61F
+ E00013AE
hpxml_schema/HPXML.xsd
@@ -375,7 +375,7 @@
hpxml_schematron/EPvalidator.xml
xml
resource
- DD7BB2F9
+ AC4BF61E
hpxml_schematron/iso-schematron.xsd
@@ -651,7 +651,7 @@
test_airflow.rb
rb
test
- D1425F08
+ D4E42045
test_battery.rb
@@ -663,7 +663,7 @@
test_defaults.rb
rb
test
- 77AFEE2C
+ 1531AC7C
test_enclosure.rb
@@ -735,7 +735,7 @@
test_validation.rb
rb
test
- 7CB39E62
+ 20E56F9D
test_water_heater.rb
diff --git a/HPXMLtoOpenStudio/resources/airflow.rb b/HPXMLtoOpenStudio/resources/airflow.rb
index d799dd5992..64df447128 100644
--- a/HPXMLtoOpenStudio/resources/airflow.rb
+++ b/HPXMLtoOpenStudio/resources/airflow.rb
@@ -1986,79 +1986,88 @@ def self.apply_cfis(runner, infil_program, vent_mech_fans, cfis_data, cfis_fan_a
infil_program.addLine("Set t_min_hr_open = #{[vent_mech.hours_in_operation / 24.0 * 60.0, 59.999].min}") # Minimum CFIS damper open time in minutes
infil_program.addLine("Set Q_duct_oa = #{UnitConversions.convert(vent_mech.oa_unit_flow_rate, 'cfm', 'm^3/s')}")
- infil_program.addLine('Set f_open_damper = 0')
infil_program.addLine("Set #{f_vent_only_mode_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
+ infil_program.addLine("Set suppl_fan_w = #{vent_mech.cfis_supplemental_fan.unit_fan_power}") # W, fan power for additional ventilation only mode runtime
+ elsif vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeAirHandler
+ infil_program.addLine("Set ah_fan_w = #{vent_mech.unit_fan_power}") # W, fan power for additional ventilation only mode runtime
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
- infil_program.addLine(' If ((Minute+0.00001) >= t_damper_open) && (has_additional_runtime == 1)') # Check whether the damper must be opened to achieve target minutes per hour of operation
- infil_program.addLine(' Set open_damper_runtime = @Max (@ABS(Minute - t_damper_open)) (fan_rtf_hvac * ZoneTimeStep * 60)') # How many minutes this timestep the damper is open
- infil_program.addLine(" Set open_damper_runtime = @Min open_damper_runtime (t_min_hr_open - #{t_sum_open_damper_var.name})") # Make sure it's not exceeding target ventilation
- infil_program.addLine(" Set #{t_sum_open_damper_var.name} = #{t_sum_open_damper_var.name} + open_damper_runtime") # How many minutes this hour the damper is open
- infil_program.addLine(' Set f_open_damper = open_damper_runtime / (60.0 * ZoneTimeStep)') # Fraction of the timestep that the damper is open
- infil_program.addLine(" Set #{f_vent_only_mode_var.name} = @Max (f_open_damper - fan_rtf_hvac) 0.0") # Fraction of the timestep with ventilation only mode runtime
- if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeAirHandler
- # Air handler meets additional runtime requirement
- infil_program.addLine(" Set fan_w = #{vent_mech.unit_fan_power}") # W
- infil_program.addLine(" Set #{cfis_fan_actuator.name} = #{cfis_fan_actuator.name} + fan_w * #{f_vent_only_mode_var.name}")
- elsif vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan
- # Supplemental fan meets additional runtime requirement
- if vent_mech.cfis_supplemental_fan.oa_unit_flow_rate < vent_mech.average_unit_flow_rate
- runner.registerWarning("CFIS supplemental fan '#{vent_mech.cfis_supplemental_fan.id}' is undersized (#{vent_mech.cfis_supplemental_fan.oa_unit_flow_rate} cfm) compared to the target hourly ventilation rate (#{vent_mech.average_unit_flow_rate} cfm).")
+ if vent_mech.cfis_control_type == HPXML::CFISControlTypeTimer
+ # Ventilation occurs at fixed intervals regardless of HVAC operation
+ infil_program.addLine('Set f_open_damper_ah = t_min_hr_open/60')
+ infil_program.addLine("Set #{f_vent_only_mode_var.name} = f_open_damper_ah * (1 - fan_rtf_hvac)") # Fraction of the timestep with ventilation only mode runtime per ANSI 301-2022 Addendum E
+ infil_program.addLine("Set #{cfis_fan_actuator.name} = #{cfis_fan_actuator.name} + (ah_fan_w * #{f_vent_only_mode_var.name})") # Fan energy associated with ventilation only mode runtime
+ elsif vent_mech.cfis_control_type == HPXML::CFISControlTypeOptimized
+ # Ventilation optimized to make use of HVAC operation
+ infil_program.addLine('Set f_open_damper = 0')
+ infil_program.addLine("Set has_additional_runtime = #{vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeNone ? 0 : 1}")
+ 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
+ infil_program.addLine(' If ((Minute+0.00001) >= t_damper_open) && (has_additional_runtime == 1)') # Check whether the damper must be opened to achieve target minutes per hour of operation
+ infil_program.addLine(' Set open_damper_runtime = @Max (@ABS(Minute - t_damper_open)) (fan_rtf_hvac * ZoneTimeStep * 60)') # How many minutes this timestep the damper is open
+ infil_program.addLine(" Set open_damper_runtime = @Min open_damper_runtime (t_min_hr_open - #{t_sum_open_damper_var.name})") # Make sure it's not exceeding target ventilation
+ infil_program.addLine(" Set #{t_sum_open_damper_var.name} = #{t_sum_open_damper_var.name} + open_damper_runtime") # How many minutes this hour the damper is open
+ infil_program.addLine(' Set f_open_damper = open_damper_runtime / (60.0 * ZoneTimeStep)') # Fraction of the timestep that the damper is open
+ infil_program.addLine(" Set #{f_vent_only_mode_var.name} = @Max (f_open_damper - fan_rtf_hvac) 0.0") # Fraction of the timestep with ventilation only mode runtime
+ if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeAirHandler
+ # Air handler meets additional runtime requirement
+ infil_program.addLine(" Set #{cfis_fan_actuator.name} = #{cfis_fan_actuator.name} + ah_fan_w * #{f_vent_only_mode_var.name}") # Fan energy associated with ventilation only mode runtime
+ elsif vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan
+ # Supplemental fan meets additional runtime requirement
+ if vent_mech.cfis_supplemental_fan.oa_unit_flow_rate < vent_mech.average_unit_flow_rate
+ runner.registerWarning("CFIS supplemental fan '#{vent_mech.cfis_supplemental_fan.id}' is undersized (#{vent_mech.cfis_supplemental_fan.oa_unit_flow_rate} cfm) compared to the target hourly ventilation rate (#{vent_mech.average_unit_flow_rate} cfm).")
+ end
+ infil_program.addLine(" Set suppl_Q_oa = #{UnitConversions.convert(vent_mech.cfis_supplemental_fan.oa_unit_flow_rate, 'cfm', 'm^3/s')}")
+ if vent_mech.cfis_supplemental_fan.oa_unit_flow_rate > 0
+ infil_program.addLine(" Set suppl_f = #{f_vent_only_mode_var.name} / (suppl_Q_oa / Q_duct_oa)") # Calculate desired runtime for supplemental fan to provide remaining ventilation requirement
+ infil_program.addLine(' Set suppl_f = @Min suppl_f 1.0') # Ensure desired runtime does not exceed 100% (if the supplemental fan is undersized)
+ else
+ infil_program.addLine(' Set suppl_f = 0.0')
+ end
+ 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)')
+ elsif vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeExhaust
+ infil_program.addLine(' Set QWHV_cfis_suppl_exh = QWHV_cfis_suppl_exh + (suppl_f * suppl_Q_oa)')
+ end
end
- infil_program.addLine(" Set suppl_Q_oa = #{UnitConversions.convert(vent_mech.cfis_supplemental_fan.oa_unit_flow_rate, 'cfm', 'm^3/s')}")
- if vent_mech.cfis_supplemental_fan.oa_unit_flow_rate > 0
- infil_program.addLine(" Set suppl_f = #{f_vent_only_mode_var.name} / (suppl_Q_oa / Q_duct_oa)") # Calculate desired runtime for supplemental fan to provide remaining ventilation requirement
- infil_program.addLine(' Set suppl_f = @Min suppl_f 1.0') # Ensure desired runtime does not exceed 100% (if the supplemental fan is undersized)
+ infil_program.addLine(' Else') # No additional ventilation mode runtime
+ infil_program.addLine(' Set open_damper_runtime = fan_rtf_hvac * ZoneTimeStep * 60') # How many minutes this timestep the damper is open
+ infil_program.addLine(" If (#{t_sum_open_damper_var.name} + open_damper_runtime) > t_min_hr_open") # Damper is only open for a portion of this time step to achieve target ventilation
+ infil_program.addLine(" Set open_damper_runtime = t_min_hr_open - #{t_sum_open_damper_var.name}")
+ infil_program.addLine(' EndIf')
+ infil_program.addLine(' Set f_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") # How many minutes this hour the damper is open
+ infil_program.addLine(' EndIf')
+ infil_program.addLine('EndIf')
+
+ # Calculate fraction of the timestep that the damper is open and the air handler fan is running
+ if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan
+ infil_program.addLine("Set f_open_damper_ah = @Max (f_open_damper - #{f_vent_only_mode_var.name}) 0.0")
else
- infil_program.addLine(' Set suppl_f = 0.0')
+ infil_program.addLine('Set f_open_damper_ah = f_open_damper')
end
- 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)')
- elsif vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeExhaust
- infil_program.addLine(' Set QWHV_cfis_suppl_exh = QWHV_cfis_suppl_exh + (suppl_f * suppl_Q_oa)')
- end
- end
- infil_program.addLine(' Else') # No additional ventilation mode runtime
- infil_program.addLine(' Set open_damper_runtime = fan_rtf_hvac * ZoneTimeStep * 60') # How many minutes this timestep the damper is open
- infil_program.addLine(" If (#{t_sum_open_damper_var.name} + open_damper_runtime) > t_min_hr_open") # Damper is only open for a portion of this time step to achieve target ventilation
- infil_program.addLine(" Set open_damper_runtime = t_min_hr_open - #{t_sum_open_damper_var.name}")
- infil_program.addLine(' EndIf')
- infil_program.addLine(' Set f_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") # How many minutes this hour the damper is open
- infil_program.addLine(' EndIf')
- infil_program.addLine('EndIf')
- # Calculate fraction of the timestep that the damper is open and the air handler fan is running
- if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan
- infil_program.addLine("Set f_open_damper_ah = @Max (f_open_damper - #{f_vent_only_mode_var.name}) 0.0")
- else
- infil_program.addLine('Set f_open_damper_ah = f_open_damper')
+ if vent_mech.cfis_addtl_runtime_operating_mode == HPXML::CFISModeSupplementalFan && vent_mech.cfis_supplemental_fan_runs_with_air_handler_fan
+ # Additionally 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_open_damper_ah)")
+ if vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeSupply
+ infil_program.addLine('Set QWHV_cfis_suppl_sup = QWHV_cfis_suppl_sup + (f_open_damper_ah * 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_open_damper_ah * suppl_Q_oa)')
+ end
+ end
end
# If no outdoor air control, then outdoor air is introduced for at least the entire time the HVAC system is running
+ infil_program.addLine("Set has_outdoor_air_control = #{vent_mech.cfis_has_outdoor_air_control ? 1 : 0}")
infil_program.addLine('If has_outdoor_air_control == 0')
infil_program.addLine(' Set f_open_damper_ah = @Max f_open_damper_ah fan_rtf_hvac')
infil_program.addLine('EndIf')
# Airflow brought in through air handler
infil_program.addLine('Set QWHV_cfis_sup = QWHV_cfis_sup + (f_open_damper_ah * 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_open_damper_ah)")
- if vent_mech.cfis_supplemental_fan.fan_type == HPXML::MechVentTypeSupply
- infil_program.addLine('Set QWHV_cfis_suppl_sup = QWHV_cfis_suppl_sup + (f_open_damper_ah * 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_open_damper_ah * suppl_Q_oa)')
- end
end
end
diff --git a/HPXMLtoOpenStudio/resources/defaults.rb b/HPXMLtoOpenStudio/resources/defaults.rb
index 9f62f339b3..02cffd792d 100644
--- a/HPXMLtoOpenStudio/resources/defaults.rb
+++ b/HPXMLtoOpenStudio/resources/defaults.rb
@@ -2759,6 +2759,10 @@ def self.apply_ventilation_fans(hpxml_bldg, weather, eri_version)
vent_fan.cfis_supplemental_fan_runs_with_air_handler_fan = false
vent_fan.cfis_supplemental_fan_runs_with_air_handler_fan_isdefaulted = true
end
+ if vent_fan.cfis_control_type.nil?
+ vent_fan.cfis_control_type = HPXML::CFISControlTypeOptimized
+ vent_fan.cfis_control_type_isdefaulted = true
+ end
end
# Default kitchen fan
diff --git a/HPXMLtoOpenStudio/resources/hpxml.rb b/HPXMLtoOpenStudio/resources/hpxml.rb
index 537abbc77d..5f0ee2f0df 100644
--- a/HPXMLtoOpenStudio/resources/hpxml.rb
+++ b/HPXMLtoOpenStudio/resources/hpxml.rb
@@ -80,6 +80,8 @@ class HPXML < Object
CertificationEnergyStar = 'Energy Star'
ClothesDryerControlTypeMoisture = 'moisture'
ClothesDryerControlTypeTimer = 'timer'
+ CFISControlTypeOptimized = 'optimized'
+ CFISControlTypeTimer = 'timer'
CFISModeAirHandler = 'air handler fan'
CFISModeNone = 'none'
CFISModeSupplementalFan = 'supplemental fan'
@@ -7999,6 +8001,7 @@ class VentilationFan < BaseElement
: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_control_type, # [String] CFISControls/extension/ControlType (HPXML::CFISControlTypeXXX)
:cfis_supplemental_fan_runs_with_air_handler_fan, # [Boolean] CFISControls/extension/SupplementalFanRunsWithAirHandlerFan
:rated_flow_rate, # [Double] RatedFlowRate (cfm)
:calculated_flow_rate, # [Double] CalculatedFlowRate (cfm)
@@ -8245,7 +8248,7 @@ 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?) || (not @cfis_supplemental_fan_runs_with_air_handler_fan.nil?)
+ if (not @cfis_addtl_runtime_operating_mode.nil?) || (not @cfis_supplemental_fan_idref.nil?) || (not @cfis_has_outdoor_air_control.nil?) || (not @cfis_control_type.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?
@@ -8253,6 +8256,7 @@ def to_doc(building)
supplemental_fan = XMLHelper.add_element(cfis_controls, 'SupplementalFan')
XMLHelper.add_attribute(supplemental_fan, 'idref', @cfis_supplemental_fan_idref)
end
+ XMLHelper.add_extension(cfis_controls, 'ControlType', @cfis_control_type, :string, @cfis_control_type_isdefaulted) unless @cfis_control_type.nil?
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?
@@ -8312,6 +8316,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_control_type = XMLHelper.get_value(ventilation_fan, 'CFISControls/extension/ControlType', :string)
@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)
diff --git a/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml b/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml
index df22728743..020226cd87 100644
--- a/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml
+++ b/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml
@@ -1961,6 +1961,7 @@
[MechanicalVentilationType=ExhaustOnly]
Expected 0 or 1 element(s) for xpath: IsSharedSystem
+ Expected 0 element(s) for xpath: CFISControls
Expected 0 or more element(s) for xpath: RatedFlowRate | CalculatedFlowRate | TestedFlowRate | DeliveredVentilation
Expected 0 or 1 element(s) for xpath: HoursInOperation
Expected 0 or 1 element(s) for xpath: FanPower
@@ -1973,6 +1974,7 @@
[MechanicalVentilationType=SupplyOnly]
Expected 0 or 1 element(s) for xpath: IsSharedSystem
+ Expected 0 element(s) for xpath: CFISControls
Expected 0 or more element(s) for xpath: RatedFlowRate | CalculatedFlowRate | TestedFlowRate | DeliveredVentilation
Expected 0 or 1 element(s) for xpath: HoursInOperation
Expected 0 or 1 element(s) for xpath: FanPower
@@ -1985,6 +1987,7 @@
[MechanicalVentilationType=Balanced]
Expected 0 or 1 element(s) for xpath: IsSharedSystem
+ Expected 0 element(s) for xpath: CFISControls
Expected 0 or more element(s) for xpath: RatedFlowRate | CalculatedFlowRate | TestedFlowRate | DeliveredVentilation
Expected 0 or 1 element(s) for xpath: HoursInOperation
Expected 0 or 1 element(s) for xpath: FanPower
@@ -1997,6 +2000,7 @@
[MechanicalVentilationType=HRV]
Expected 0 or 1 element(s) for xpath: IsSharedSystem
+ Expected 0 element(s) for xpath: CFISControls
Expected 0 or more element(s) for xpath: RatedFlowRate | CalculatedFlowRate | TestedFlowRate | DeliveredVentilation
Expected 0 or 1 element(s) for xpath: HoursInOperation
Expected 0 element(s) for xpath: AdjustedTotalRecoveryEfficiency | TotalRecoveryEfficiency
@@ -2009,6 +2013,7 @@
[MechanicalVentilationType=ERV]
Expected 0 or 1 element(s) for xpath: IsSharedSystem
+ Expected 0 element(s) for xpath: CFISControls
Expected 0 or more element(s) for xpath: RatedFlowRate | CalculatedFlowRate | TestedFlowRate | DeliveredVentilation
Expected 0 or 1 element(s) for xpath: HoursInOperation
Expected 1 element(s) for xpath: AdjustedTotalRecoveryEfficiency | TotalRecoveryEfficiency
@@ -2027,6 +2032,8 @@
Expected 0 or 1 element(s) for xpath: CFISControls/HasOutdoorAirControl
Expected 0 or 1 element(s) for xpath: CFISControls/AdditionalRuntimeOperatingMode
Expected CFISControls/AdditionalRuntimeOperatingMode to be 'air handler fan' or 'supplemental fan' or 'none'
+ Expected 0 or 1 element(s) for xpath: CFISControls/extension/ControlType
+ Expected CFISControls/extension/ControlType to be 'optimized' or 'timer'
Expected 0 or more element(s) for xpath: RatedFlowRate | CalculatedFlowRate | TestedFlowRate | DeliveredVentilation
Expected 0 or 1 element(s) for xpath: HoursInOperation
Expected 0 element(s) for xpath: TotalRecoveryEfficiency | AdjustedTotalRecoveryEfficiency
@@ -2034,6 +2041,13 @@
Expected 1 element(s) for xpath: AttachedToHVACDistributionSystem
+
+
+ [CFISControlType=Timer]
+
+ Expected CFISControls/AdditionalRuntimeOperatingMode to be 'air handler fan'
+
+
[CFISAdditionalRuntimeMode=AirHandlerFan]
diff --git a/HPXMLtoOpenStudio/tests/test_airflow.rb b/HPXMLtoOpenStudio/tests/test_airflow.rb
index a47a60b2bd..114a01234c 100644
--- a/HPXMLtoOpenStudio/tests/test_airflow.rb
+++ b/HPXMLtoOpenStudio/tests/test_airflow.rb
@@ -384,7 +384,7 @@ def test_mechanical_ventilation_cfis
assert_in_epsilon(vent_fan_cfm, UnitConversions.convert(program_values['Q_duct_oa'].sum, 'm^3/s', 'cfm'), 0.01)
assert_in_epsilon(0.0, UnitConversions.convert(program_values['QWHV_sup'].sum, 'm^3/s', 'cfm'), 0.01)
assert_in_epsilon(0.0, UnitConversions.convert(program_values['QWHV_exh'].sum, 'm^3/s', 'cfm'), 0.01)
- assert_in_epsilon(vent_fan_power, program_values['fan_w'].sum, 0.01)
+ assert_in_epsilon(vent_fan_power, program_values['ah_fan_w'].sum, 0.01)
assert_in_epsilon(vent_fan_mins, program_values['t_min_hr_open'].sum, 0.01)
assert_in_epsilon(0.0, UnitConversions.convert(program_values['Qrange'].sum, 'm^3/s', 'cfm'), 0.01)
assert_in_epsilon(0.0, UnitConversions.convert(program_values['Qbath'].sum, 'm^3/s', 'cfm'), 0.01)
@@ -516,7 +516,7 @@ def test_multiple_mechvent
assert_equal(1, get_eed_for_ventilation(model, Constants::ObjectTypeMechanicalVentilationHouseFan).size)
assert_in_epsilon(total_mechvent_pow, get_eed_for_ventilation(model, Constants::ObjectTypeMechanicalVentilationHouseFan)[0].designLevel.get, 0.01)
assert_in_epsilon(fraction_heat_lost, get_eed_for_ventilation(model, Constants::ObjectTypeMechanicalVentilationHouseFan)[0].fractionLost, 0.01)
- assert_in_epsilon(vent_fan_power_cfis, program_values['fan_w'].sum, 0.01)
+ assert_in_epsilon(vent_fan_power_cfis, program_values['ah_fan_w'].sum, 0.01)
range_fan_eeds = get_eed_for_ventilation(model, Constants::ObjectTypeMechanicalVentilationRangeFan)
assert_equal(2, range_fan_eeds.size)
assert_in_epsilon(kitchen_fan_power, range_fan_eeds.map { |f| f.designLevel.get }.sum(0.0), 0.01)
@@ -573,7 +573,7 @@ def test_shared_mechvent_multiple
program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{Constants::ObjectTypeInfiltration} program")
assert_in_epsilon((vent_fans_cfm_oa_preheat_sup + vent_fans_cfm_oa_preheat_bal + vent_fans_cfm_oa_preheat_ervhrv), UnitConversions.convert(program_values['Qpreheat'].sum, 'm^3/s', 'cfm'), 0.01)
assert_in_epsilon((vent_fans_cfm_oa_precool_sup + vent_fans_cfm_oa_precool_bal + vent_fans_cfm_oa_precool_ervhrv), UnitConversions.convert(program_values['Qprecool'].sum, 'm^3/s', 'cfm'), 0.01)
- assert_in_epsilon(vent_fans_pow_cfis, program_values['fan_w'].sum, 0.01)
+ assert_in_epsilon(vent_fans_pow_cfis, program_values['ah_fan_w'].sum, 0.01)
assert_in_epsilon(vent_fans_mins_cfis, program_values['t_min_hr_open'].sum, 0.01)
assert_in_epsilon(vent_fans_cfm_oa_cfis, UnitConversions.convert(program_values['Q_duct_oa'].sum, 'm^3/s', 'cfm'), 0.01)
assert_in_epsilon(vent_fans_cfm_tot_sup + vent_fans_cfm_tot_ervhrvbal, UnitConversions.convert(program_values['QWHV_sup'].sum, 'm^3/s', 'cfm'), 0.01)
diff --git a/HPXMLtoOpenStudio/tests/test_defaults.rb b/HPXMLtoOpenStudio/tests/test_defaults.rb
index e8fcf4d0d4..5898508740 100644
--- a/HPXMLtoOpenStudio/tests/test_defaults.rb
+++ b/HPXMLtoOpenStudio/tests/test_defaults.rb
@@ -3018,9 +3018,10 @@ def test_mech_ventilation_fans
vent_fan.rated_flow_rate = 222.0
vent_fan.cfis_vent_mode_airflow_fraction = 0.5
vent_fan.cfis_has_outdoor_air_control = false
+ vent_fan.cfis_control_type = HPXML::CFISControlTypeTimer
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
_default_hpxml, default_hpxml_bldg = _test_measure()
- _test_default_mech_vent_values(default_hpxml_bldg, false, 12.0, 12.5, 222.0, 0.5, HPXML::CFISModeAirHandler, false)
+ _test_default_mech_vent_values(default_hpxml_bldg, false, 12.0, 12.5, 222.0, 0.5, HPXML::CFISModeAirHandler, false, HPXML::CFISControlTypeTimer)
# Test defaults w/ CFIS
vent_fan.is_shared_system = nil
@@ -3030,9 +3031,10 @@ def test_mech_ventilation_fans
vent_fan.cfis_vent_mode_airflow_fraction = nil
vent_fan.cfis_addtl_runtime_operating_mode = nil
vent_fan.cfis_has_outdoor_air_control = nil
+ vent_fan.cfis_control_type = nil
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
_default_hpxml, default_hpxml_bldg = _test_measure()
- _test_default_mech_vent_values(default_hpxml_bldg, false, 8.0, 300.0, 305.4, 1.0, HPXML::CFISModeAirHandler, true)
+ _test_default_mech_vent_values(default_hpxml_bldg, false, 8.0, 300.0, 305.4, 1.0, HPXML::CFISModeAirHandler, true, HPXML::CFISControlTypeOptimized)
# Test inputs not overridden by defaults w/ CFIS & supplemental fan
hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-supplemental-fan-exhaust.xml')
@@ -3045,7 +3047,7 @@ def test_mech_ventilation_fans
suppl_vent_fan.fan_power = 9.0
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
_default_hpxml, default_hpxml_bldg = _test_measure()
- _test_default_mech_vent_values(default_hpxml_bldg, false, 12.0, nil, 222.0, nil, HPXML::CFISModeSupplementalFan, true, true)
+ _test_default_mech_vent_values(default_hpxml_bldg, false, 12.0, nil, 222.0, nil, HPXML::CFISModeSupplementalFan, true, HPXML::CFISControlTypeOptimized, true)
_test_default_mech_vent_suppl_values(default_hpxml_bldg, false, nil, 9.0, 79.0)
# Test defaults w/ CFIS & supplemental fan
@@ -3058,7 +3060,7 @@ def test_mech_ventilation_fans
vent_fan.cfis_supplemental_fan_runs_with_air_handler_fan = nil
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
_default_hpxml, default_hpxml_bldg = _test_measure()
- _test_default_mech_vent_values(default_hpxml_bldg, false, 8.0, nil, 305.4, nil, HPXML::CFISModeSupplementalFan, true, false)
+ _test_default_mech_vent_values(default_hpxml_bldg, false, 8.0, nil, 305.4, nil, HPXML::CFISModeSupplementalFan, true, HPXML::CFISControlTypeOptimized, false)
# Test defaults w/ CFIS supplemental fan
suppl_vent_fan.tested_flow_rate = nil
@@ -5450,7 +5452,7 @@ def _test_default_hydronic_distribution_values(hpxml_bldg, manualj_hot_water_pip
def _test_default_mech_vent_values(hpxml_bldg, is_shared_system, hours_in_operation, fan_power, flow_rate,
cfis_vent_mode_airflow_fraction = nil, cfis_addtl_runtime_operating_mode = nil,
- cfis_has_outdoor_air_control = nil, cfis_suppl_fan_runs_with_air_handler = nil)
+ cfis_has_outdoor_air_control = nil, cfis_control_type = nil, cfis_suppl_fan_runs_with_air_handler = nil)
vent_fan = hpxml_bldg.ventilation_fans.find { |f| f.used_for_whole_building_ventilation && !f.is_cfis_supplemental_fan }
assert_equal(is_shared_system, vent_fan.is_shared_system)
@@ -5481,6 +5483,11 @@ def _test_default_mech_vent_values(hpxml_bldg, is_shared_system, hours_in_operat
else
assert_equal(cfis_suppl_fan_runs_with_air_handler, vent_fan.cfis_supplemental_fan_runs_with_air_handler_fan)
end
+ if cfis_control_type.nil?
+ assert_nil(vent_fan.cfis_control_type)
+ else
+ assert_equal(cfis_control_type, vent_fan.cfis_control_type)
+ end
end
def _test_default_mech_vent_suppl_values(hpxml_bldg, is_shared_system, hours_in_operation, fan_power, flow_rate)
diff --git a/HPXMLtoOpenStudio/tests/test_validation.rb b/HPXMLtoOpenStudio/tests/test_validation.rb
index 538f12a0f1..d91daf8e30 100644
--- a/HPXMLtoOpenStudio/tests/test_validation.rb
+++ b/HPXMLtoOpenStudio/tests/test_validation.rb
@@ -159,6 +159,7 @@ def test_schema_schematron_error_messages
'invalid-calendar-year-high' => ['Expected CalendarYear to be less than or equal to 9999'],
'invalid-clothes-dryer-cef' => ["Element 'CombinedEnergyFactor': [facet 'minExclusive'] The value '0.0' must be greater than '0'."],
'invalid-clothes-washer-imef' => ["Element 'IntegratedModifiedEnergyFactor': [facet 'minExclusive'] The value '0.0' must be greater than '0'."],
+ 'invalid-cfis-addtl-runtime-mode' => ["Expected CFISControls/AdditionalRuntimeOperatingMode to be 'air handler fan'"],
'invalid-dishwasher-ler' => ["Element 'LabelElectricRate': [facet 'minExclusive'] The value '0.0' must be greater than '0'."],
'invalid-duct-area-fractions' => ['Expected sum(Ducts/FractionDuctArea) for DuctType="supply" to be 1 [context: /HPXML/Building/BuildingDetails/Systems/HVAC/HVACDistribution/DistributionSystemType/AirDistribution, id: "HVACDistribution1"]',
'Expected sum(Ducts/FractionDuctArea) for DuctType="return" to be 1 [context: /HPXML/Building/BuildingDetails/Systems/HVAC/HVACDistribution/DistributionSystemType/AirDistribution, id: "HVACDistribution1"]'],
@@ -538,6 +539,10 @@ def test_schema_schematron_error_messages
elsif ['invalid-clothes-washer-imef'].include? error_case
hpxml, hpxml_bldg = _create_hpxml('base.xml')
hpxml_bldg.clothes_washers[0].integrated_modified_energy_factor = 0
+ elsif ['invalid-cfis-addtl-runtime-mode'].include? error_case
+ hpxml, hpxml_bldg = _create_hpxml('base-mechvent-cfis-control-type-timer.xml')
+ hpxml_bldg.ventilation_fans[0].cfis_addtl_runtime_operating_mode = HPXML::CFISModeNone
+ hpxml_bldg.ventilation_fans[0].fan_power = nil
elsif ['invalid-dishwasher-ler'].include? error_case
hpxml, hpxml_bldg = _create_hpxml('base.xml')
hpxml_bldg.dishwashers[0].label_electric_rate = 0
diff --git a/docs/source/workflow_inputs.rst b/docs/source/workflow_inputs.rst
index 722ea85d65..1582875051 100644
--- a/docs/source/workflow_inputs.rst
+++ b/docs/source/workflow_inputs.rst
@@ -3780,6 +3780,7 @@ A CFIS system is a supply ventilation system that provides outdoor air to the re
``CFISControls/HasOutdoorAirControl`` boolean No true Presence of controls to block outdoor air when not ventilating [#]_
``CFISControls/AdditionalRuntimeOperatingMode`` string See [#]_ No air handler fan How additional ventilation is provided (beyond HVAC system operation)
``CFISControls/SupplementalFan`` idref See [#]_ See [#]_ The supplemental fan providing additional ventilation
+ ``CFISControls/extension/ControlType`` string See [#]_ No optimized Primary air handler fan control strategy [#]_
``CFISControls/extension/SupplementalFanRunsWithAirHandlerFan`` boolean No [#]_ false Whether the supplemental fan also runs with the air handler fan [#]_
``RatedFlowRate`` or ``TestedFlowRate`` or ``CalculatedFlowRate`` or ``DeliveredVentilation`` double cfm >= 0 No See [#]_ Flow rate [#]_
``HoursInOperation`` double hrs/day >= 0, <= 24 false 8 Hours per day of operation [#]_
@@ -3793,9 +3794,12 @@ A CFIS system is a supply ventilation system that provides outdoor air to the re
.. [#] AdditionalRuntimeOperatingMode choices are "air handler fan", "supplemental fan", or "none".
.. [#] SupplementalFan must reference another ``VentilationFan`` where UsedForWholeBuildingVentilation=true, IsSharedSystem=false, and FanType="exhaust only" or "supply only".
.. [#] SupplementalFan only required if AdditionalRuntimeOperatingMode is "supplemental fan".
+ .. [#] ControlType choices are "optimized" or "timer; "timer" is only allowed if AdditionalRuntimeOperatingMode="air handler fan".
+ .. [#] If ControlType="optimized", ventilation operation is assumed to take advantage of normal HVAC operation as much as possible, resulting in the lowest possible air handler fan energy use.
+ If ControlType="timer", ventilation operation occurs at a fixed interval and may fully, partially, or not coincide with HVAC operation for a given hour, resulting in higher air handler fan energy use.
.. [#] SupplementalFanRunsWithAirHandlerFan only applies when AdditionalRuntimeOperatingMode="supplemental fan".
.. [#] If SupplementalFanRunsWithAirHandlerFan is true, in addition to its normal operation, the supplemental fan will also run simultaneously with the air handler fan when outdoor air is being brought in.
- This is typically used with a supplemental exhaust fan to provide "balanced" (supply + exhaust) airflow.
+ This is typically used with a supplemental exhaust fan to provide balanced (supply + exhaust) airflow, though any additional runtime where the supplemental fan runs by itself will still be imbalanced.
.. [#] If flow rate not provided, defaults to the required mechanical ventilation rate per `ANSI/RESNET/ICC 301-2022 `_:
Qfan = required mechanical ventilation rate (cfm) = ((Qtot^2 – 4*Qinf_eff^2 + 2*Qinf_eff*Qtot + Qinf_eff^2)^0.5 + Qtot - Qinf_eff) / 2
diff --git a/tasks.rb b/tasks.rb
index dfa5ba2190..6e758c7068 100644
--- a/tasks.rb
+++ b/tasks.rb
@@ -2275,6 +2275,8 @@ def apply_hpxml_modification_sample_files(hpxml_path, hpxml)
used_for_whole_building_ventilation: true)
elsif ['base-mechvent-cfis-airflow-fraction-zero.xml'].include? hpxml_file
hpxml_bldg.ventilation_fans[0].cfis_vent_mode_airflow_fraction = 0.0
+ elsif ['base-mechvent-cfis-control-type-timer.xml'].include? hpxml_file
+ hpxml_bldg.ventilation_fans[0].cfis_control_type = HPXML::CFISControlTypeTimer
elsif ['base-mechvent-cfis-no-additional-runtime.xml'].include? hpxml_file
hpxml_bldg.ventilation_fans[0].cfis_addtl_runtime_operating_mode = HPXML::CFISModeNone
elsif ['base-mechvent-cfis-no-outdoor-air-control.xml'].include? hpxml_file
diff --git a/workflow/hpxml_inputs.json b/workflow/hpxml_inputs.json
index 3ed9121fbc..954643115d 100644
--- a/workflow/hpxml_inputs.json
+++ b/workflow/hpxml_inputs.json
@@ -3184,6 +3184,9 @@
"sample_files/base-mechvent-cfis-airflow-fraction-zero.xml": {
"parent_hpxml": "sample_files/base-mechvent-cfis.xml"
},
+ "sample_files/base-mechvent-cfis-control-type-timer.xml": {
+ "parent_hpxml": "sample_files/base-mechvent-cfis.xml"
+ },
"sample_files/base-mechvent-cfis-dse.xml": {
"parent_hpxml": "sample_files/base-hvac-dse.xml",
"mech_vent_fan_type": "central fan integrated supply",
diff --git a/workflow/sample_files/base-mechvent-cfis-control-type-timer.xml b/workflow/sample_files/base-mechvent-cfis-control-type-timer.xml
new file mode 100644
index 0000000000..e554534cdc
--- /dev/null
+++ b/workflow/sample_files/base-mechvent-cfis-control-type-timer.xml
@@ -0,0 +1,570 @@
+
+
+
+ HPXML
+ tasks.rb
+ 2000-01-01T00:00:00-07:00
+ create
+
+
+
+
+ 60
+
+
+
+ Bills
+
+
+
+
+
+
+
+
+
+ CO
+
+
+
+ proposed workscope
+
+
+
+
+ suburban
+ stand-alone
+ no units above or below
+ 180
+
+ electricity
+ natural gas
+
+
+
+ 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
+
+
+
+
+
+
+
+
+
+ central fan integrated supply
+
+ air handler fan
+
+ timer
+
+
+ 330.0
+ 8.0
+ true
+ 300.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
diff --git a/workflow/tests/base_results/results_simulations_bills.csv b/workflow/tests/base_results/results_simulations_bills.csv
index 95a14683c4..1d0840593f 100644
--- a/workflow/tests/base_results/results_simulations_bills.csv
+++ b/workflow/tests/base_results/results_simulations_bills.csv
@@ -360,6 +360,7 @@ base-location-portland-or.xml,1210.6,144.0,817.39,0.0,961.39,144.0,105.21,249.21
base-mechvent-balanced.xml,2112.11,144.0,1376.02,0.0,1520.02,144.0,448.09,592.09,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-bath-kitchen-fans.xml,1863.27,144.0,1307.24,0.0,1451.24,144.0,268.03,412.03,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-airflow-fraction-zero.xml,2042.44,144.0,1370.06,0.0,1514.06,144.0,384.38,528.38,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-control-type-timer.xml,2097.8,144.0,1404.85,0.0,1548.85,144.0,404.95,548.95,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-dse.xml,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-evap-cooler-only-ducted.xml,1366.37,144.0,1222.37,0.0,1366.37,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-no-additional-runtime.xml,1928.74,144.0,1312.33,0.0,1456.33,144.0,328.41,472.41,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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 8b9b020e31..235d096603 100644
--- a/workflow/tests/base_results/results_simulations_energy.csv
+++ b/workflow/tests/base_results/results_simulations_energy.csv
@@ -360,6 +360,7 @@ base-location-portland-or.xml,37.945,37.945,27.21,27.21,10.734,0.0,0.0,0.0,0.0,0
base-mechvent-balanced.xml,80.609,80.609,37.803,37.803,42.805,0.0,0.0,0.0,0.0,0.0,0.0,1.062,0.0,0.0,4.195,0.615,9.019,0.0,0.0,4.507,0.0,0.334,1.793,0.0,0.0,0.0,2.053,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,0.0,0.0,0.0,42.805,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-bath-kitchen-fans.xml,61.518,61.518,35.914,35.914,25.605,0.0,0.0,0.0,0.0,0.0,0.0,0.635,0.0,0.0,4.362,0.654,9.015,0.0,0.0,4.507,0.0,0.334,0.112,0.0,0.0,0.0,2.07,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,0.0,0.0,0.0,25.605,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-airflow-fraction-zero.xml,74.359,74.359,37.64,37.64,36.719,0.0,0.0,0.0,0.0,0.0,0.0,0.911,0.0,0.0,4.273,0.632,9.017,0.0,0.0,4.507,0.0,0.334,1.681,0.0,0.0,0.0,2.059,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,0.0,0.0,0.0,36.719,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-control-type-timer.xml,77.28,77.28,38.595,38.595,38.685,0.0,0.0,0.0,0.0,0.0,0.0,0.96,0.0,0.0,4.407,0.655,9.018,0.0,0.0,4.507,0.0,0.334,2.434,0.0,0.0,0.0,2.057,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,0.0,0.0,0.0,38.685,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-dse.xml,74.313,74.313,38.621,38.621,35.692,0.0,0.0,0.0,0.0,0.0,0.0,0.886,0.0,0.0,5.043,0.712,9.017,0.0,0.0,4.507,0.0,0.334,1.839,0.0,0.0,0.0,2.059,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,0.0,0.0,0.0,35.692,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-evap-cooler-only-ducted.xml,33.582,33.582,33.582,33.582,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.837,9.084,0.0,0.0,4.507,0.0,0.334,2.771,0.0,0.0,0.0,1.824,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,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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-mechvent-cfis-no-additional-runtime.xml,67.426,67.426,36.054,36.054,31.372,0.0,0.0,0.0,0.0,0.0,0.0,0.778,0.0,0.0,4.455,0.669,9.014,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,0.0,0.0,0.0,31.372,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,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_hvac.csv b/workflow/tests/base_results/results_simulations_hvac.csv
index 6b094ba7c0..97ee0b80a9 100644
--- a/workflow/tests/base_results/results_simulations_hvac.csv
+++ b/workflow/tests/base_results/results_simulations_hvac.csv
@@ -360,6 +360,7 @@ base-location-portland-or.xml,28.58,87.08,24000.0,24000.0,0.0,17789.0,6513.0,492
base-mechvent-balanced.xml,6.8,91.76,36000.0,24000.0,0.0,38765.0,8862.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,4620.0,6372.0,0.0,21660.0,6043.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,622.0,1690.0,3320.0,0.0,0.0,-1656.0,0.0,-661.0,-1795.0,800.0
base-mechvent-bath-kitchen-fans.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-mechvent-cfis-airflow-fraction-zero.xml,6.8,91.76,36000.0,24000.0,0.0,33814.0,8531.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,0.0,6372.0,0.0,21135.0,6140.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,0.0,1690.0,3320.0,0.0,0.0,-995.0,0.0,0.0,-1795.0,800.0
+base-mechvent-cfis-control-type-timer.xml,6.8,91.76,36000.0,24000.0,0.0,33814.0,8531.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,0.0,6372.0,0.0,21135.0,6140.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,0.0,1690.0,3320.0,0.0,0.0,-995.0,0.0,0.0,-1795.0,800.0
base-mechvent-cfis-dse.xml,6.8,91.76,36000.0,24000.0,0.0,25282.0,0.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,0.0,6372.0,0.0,14995.0,0.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,0.0,1690.0,3320.0,0.0,0.0,-995.0,0.0,0.0,-1795.0,800.0
base-mechvent-cfis-evap-cooler-only-ducted.xml,6.8,91.76,0.0,24000.0,0.0,25282.0,0.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,0.0,6372.0,0.0,17555.0,2561.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,0.0,1690.0,3320.0,0.0,0.0,-995.0,0.0,0.0,-1795.0,800.0
base-mechvent-cfis-no-additional-runtime.xml,6.8,91.76,36000.0,24000.0,0.0,33814.0,8531.0,7508.0,0.0,575.0,6918.0,0.0,0.0,1738.0,2171.0,0.0,6372.0,0.0,21135.0,6140.0,7037.0,0.0,207.0,448.0,0.0,0.0,0.0,2293.0,0.0,1690.0,3320.0,0.0,0.0,-995.0,0.0,0.0,-1795.0,800.0
diff --git a/workflow/tests/base_results/results_simulations_loads.csv b/workflow/tests/base_results/results_simulations_loads.csv
index ca64888e55..78865b7d7b 100644
--- a/workflow/tests/base_results/results_simulations_loads.csv
+++ b/workflow/tests/base_results/results_simulations_loads.csv
@@ -360,6 +360,7 @@ base-location-portland-or.xml,9.941,0.0,8.005,8.724,0.78,0.0,0.0,0.0,3.137,2.898
base-mechvent-balanced.xml,40.449,0.0,12.716,9.071,0.621,0.0,0.0,0.0,3.768,3.998,0.561,7.341,0.702,11.216,-14.601,0.0,0.0,0.0,8.3,-0.244,5.6,0.0,16.41,0.0,9.127,-9.184,-2.867,0.0,0.284,0.049,0.019,2.964,0.085,0.202,9.812,0.0,0.0,0.0,-5.701,-0.241,-0.525,-3.116,-2.142,0.0,3.075,6.384,1.641
base-mechvent-bath-kitchen-fans.xml,24.191,0.0,13.576,9.071,0.616,0.0,0.0,0.0,3.825,3.905,0.548,7.556,0.688,10.829,-13.686,0.0,0.0,0.0,8.336,-0.125,4.855,0.0,2.662,0.0,5.695,-8.56,-2.693,0.0,0.07,-0.152,-0.009,2.852,0.044,-0.522,10.727,0.0,0.0,0.0,-6.111,-0.121,-0.732,-3.793,-0.483,0.0,3.095,7.019,1.814
base-mechvent-cfis-airflow-fraction-zero.xml,34.698,0.0,13.078,9.071,0.619,0.0,0.0,0.0,3.798,3.98,0.559,7.43,0.701,11.152,-14.238,0.0,0.0,0.0,8.232,-0.222,1.722,0.0,15.099,0.0,7.936,-8.963,-2.806,0.0,0.22,-0.013,0.011,2.929,0.074,0.004,10.175,0.0,0.0,0.0,-5.945,-0.218,-0.148,-3.365,-1.962,0.0,3.106,6.61,1.701
+base-mechvent-cfis-control-type-timer.xml,36.555,0.0,13.551,9.071,0.619,0.0,0.0,0.0,3.691,3.999,0.561,7.372,0.704,11.209,-14.382,0.0,0.0,0.0,8.189,-0.264,1.732,0.0,14.668,0.0,10.625,-9.041,-2.826,0.0,0.281,0.02,0.015,2.911,0.08,0.106,10.031,0.0,0.0,0.0,-5.924,-0.261,-0.147,-3.26,-1.59,0.0,3.186,6.53,1.681
base-mechvent-cfis-dse.xml,26.959,0.0,10.124,9.071,0.619,0.0,0.0,0.0,4.221,3.977,0.558,7.419,0.701,11.142,-14.238,0.0,0.0,0.0,8.209,-0.222,1.666,0.0,14.975,0.0,0.0,-8.963,-2.806,0.0,0.368,-0.014,0.01,2.926,0.074,0.001,10.175,0.0,0.0,0.0,-5.953,-0.218,-0.15,-3.362,-1.929,0.0,0.0,6.61,1.701
base-mechvent-cfis-evap-cooler-only-ducted.xml,0.0,0.0,10.579,9.071,0.69,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.0,0.389,0.053,0.019,2.824,0.09,0.196,9.632,0.0,0.0,0.0,-6.055,-0.263,-0.14,-3.152,-1.452,0.0,0.66,6.271,1.619
base-mechvent-cfis-no-additional-runtime.xml,29.643,0.0,13.898,9.071,0.615,0.0,0.0,0.0,3.742,3.883,0.545,7.571,0.682,10.761,-13.574,0.0,0.0,0.0,8.367,-0.116,2.979,0.0,8.67,0.0,6.913,-8.475,-2.662,0.0,0.025,-0.187,-0.014,2.828,0.035,-0.631,10.839,0.0,0.0,0.0,-6.136,-0.112,-0.815,-3.874,-0.103,0.0,3.21,7.106,1.845
diff --git a/workflow/tests/base_results/results_simulations_misc.csv b/workflow/tests/base_results/results_simulations_misc.csv
index 69c01a2007..825546a4f7 100644
--- a/workflow/tests/base_results/results_simulations_misc.csv
+++ b/workflow/tests/base_results/results_simulations_misc.csv
@@ -360,6 +360,7 @@ base-location-portland-or.xml,0.0,0.0,1354.7,998.0,11014.7,2714.0,1626.8,2923.0,
base-mechvent-balanced.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2220.5,3787.6,3787.6,33.272,21.071,0.0
base-mechvent-bath-kitchen-fans.xml,0.0,0.0,1354.7,998.0,11171.5,2563.5,2094.5,3719.8,3719.8,26.161,20.522,0.0
base-mechvent-cfis-airflow-fraction-zero.xml,0.0,0.0,1354.7,998.0,11171.5,2563.5,2127.6,3702.5,3702.5,29.917,20.765,0.0
+base-mechvent-cfis-control-type-timer.xml,0.0,0.0,1354.7,998.0,11171.5,2563.5,2168.9,3768.8,3768.8,29.895,20.834,0.0
base-mechvent-cfis-dse.xml,0.0,0.0,1354.7,998.0,11171.5,2563.5,2085.1,2926.2,2926.2,21.554,13.58,0.0
base-mechvent-cfis-evap-cooler-only-ducted.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2018.6,2306.5,2306.5,0.0,16.216,0.0
base-mechvent-cfis-no-additional-runtime.xml,0.0,0.0,1354.7,998.0,11171.6,2563.5,2135.2,4049.8,4049.8,29.918,20.857,0.0