Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
8758181
Add new sample files for heat pump with hvac seasons, power outage.
joseph-robertson Jan 21, 2026
aae60b1
Add crankcase ems program, and use hvac seasons and unavailability pe…
joseph-robertson Jan 21, 2026
e1c4950
Update tests and docs.
joseph-robertson Jan 21, 2026
0ff6650
Merge branch 'master' into address-crankcase-defrost-pan-warning
joseph-robertson Jan 22, 2026
1a40627
Crankcase into its own program, and remove season from pan and crankc…
joseph-robertson Jan 22, 2026
554afd1
Update defrost/pan/crankcase ems test for crankcase changes.
joseph-robertson Jan 22, 2026
2873982
Remove old crankcase unit test.
joseph-robertson Jan 22, 2026
e526e25
Deal with crankcase allocation to heating or cooling.
joseph-robertson Jan 22, 2026
6eeaa29
Latest results.
Jan 23, 2026
3316eab
Crankcase allows zero capacity; slight program fix.
joseph-robertson Jan 26, 2026
51bb6a7
Latest results.
Jan 26, 2026
897e276
Merge branch 'master' into address-crankcase-defrost-pan-warning
joseph-robertson Jan 26, 2026
a215af2
Use heating and/or cooling availability sensors for crankcase operation.
joseph-robertson Jan 26, 2026
8ba115f
Latest results.
Jan 26, 2026
3a05c70
Use heating coil runtime fraction for crankcase calculation.
joseph-robertson Jan 27, 2026
8c263cb
Revise and simplify ems logic for unavailable periods.
joseph-robertson Jan 27, 2026
61a3792
Revert clg_coil addition in hvac test.
joseph-robertson Jan 27, 2026
c1c8046
Latest results.
Jan 27, 2026
9345759
Set additional properties for hp heating tout and rtf sensors.
joseph-robertson Feb 2, 2026
2abcd8e
Update measure xml.
joseph-robertson Feb 2, 2026
cd0d7ab
Merge branch 'master' into address-crankcase-defrost-pan-warning
joseph-robertson Feb 2, 2026
641094c
Put hp heating tout and rtf sensors upstream of defrost and crankcase.
joseph-robertson Feb 2, 2026
5e0541d
Introduce a new sensor for unitary system.
joseph-robertson Feb 2, 2026
ecdc565
Bring cycling ratio into the calculation for multispeed objects.
joseph-robertson Feb 2, 2026
c8dd252
Update measure xml file.
joseph-robertson Feb 2, 2026
f1da956
Organize ems sensors.
joseph-robertson Feb 3, 2026
b85e3c4
Introduce the cooling coil runtime fraction sensor.
joseph-robertson Feb 3, 2026
5147828
Latest results.
Feb 3, 2026
ba58f27
Merge branch 'master' into address-crankcase-defrost-pan-warning
joseph-robertson Feb 4, 2026
a4f9f01
Latest results.
Feb 5, 2026
13fab78
Merge branch 'master' into address-crankcase-defrost-pan-warning
joseph-robertson Feb 9, 2026
fd4513d
Latest results.
Feb 9, 2026
63dd002
Merge branch 'master' into address-crankcase-defrost-pan-warning
joseph-robertson Mar 6, 2026
439a213
Remove model from being passed into get_object_outputs_by_key.
joseph-robertson Mar 6, 2026
76cddff
Latest results.
Mar 7, 2026
5c2f362
Merge branch 'master' into address-crankcase-defrost-pan-warning
joseph-robertson Mar 12, 2026
54238a3
Latest results.
Mar 12, 2026
2afbc95
Change calling point InsideHVACSystemIterationLoop -> EndOfSystemTime…
joseph-robertson Mar 13, 2026
44ea2e1
Latest results.
Mar 13, 2026
5e820e6
Replace a few remaining TODO comments. [ci skip]
joseph-robertson Mar 16, 2026
c585f32
Update the changelog. [ci skip]
joseph-robertson Mar 16, 2026
5e8f794
Merge branch 'master' into address-crankcase-defrost-pan-warning
joseph-robertson Mar 31, 2026
69e7703
Remove passing model into get_object_outputs_by_key.
joseph-robertson Mar 31, 2026
a6d7be1
Latest results.
Mar 31, 2026
546ddbb
Merge branch 'master' of https://github.com/NatLabRockies/OpenStudio-…
shorowit Apr 6, 2026
9c4b80b
Latest results.
Apr 6, 2026
6434c0e
Merge branch 'master' of https://github.com/NatLabRockies/OpenStudio-…
shorowit Apr 20, 2026
cbc3a2d
Latest results.
Apr 20, 2026
8eefb0d
Bit of refactoring around variable definitions, per review.
joseph-robertson Apr 21, 2026
747e359
Update the new changelog entry.
joseph-robertson Apr 21, 2026
031529b
Include availability sensors in compressor lockout program line.
joseph-robertson Apr 21, 2026
56b8ab9
Latest results.
Apr 22, 2026
4259784
Simplify logic; no diffs expected.
shorowit Apr 22, 2026
a94605b
Merge branch 'master' of https://github.com/NatLabRockies/OpenStudio-…
shorowit Apr 22, 2026
e254a2b
Merge branch 'master' of https://github.com/NatLabRockies/OpenStudio-…
shorowit Apr 23, 2026
af6e7cf
Update crankcase heater run logic during unavailable periods.
joseph-robertson Apr 23, 2026
60e8f0c
Merge branch 'address-crankcase-defrost-pan-warning' of github.com:NR…
joseph-robertson Apr 23, 2026
1f5d5b2
Latest results. [skip ci]
Apr 23, 2026
2b44b26
Merge branch 'master' of https://github.com/NatLabRockies/OpenStudio-…
shorowit Apr 24, 2026
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
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ __New Features__
- HVAC updates:
- Dual-fuel heat pumps with switchover temperatures > 25F are now autosized based on 25F to allow some additional heating capacity buffer.
- Improves handling of duct leakage specified using cfm25/cfm50.
- Crankcase heating energy is now disabled during unavailable periods, e.g., power outages.
- Allows "other" for `SoilType`; adds variation to dry/wet soil conductivity and diffusivity values for unknown/other/loam soil types.
- Output updates:
- **Breaking change**: Annual peak load outputs for heating and cooling now use units of Btu/h instead of kBtu/h for consistency with other outputs.
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>hpxml_to_openstudio</name>
<uid>b1543b30-9465-45ff-ba04-1d1f85e763bc</uid>
<version_id>3fbd03a7-2588-4857-bfac-6ced25e2a6c3</version_id>
<version_modified>2026-04-24T02:56:02Z</version_modified>
<version_id>b75fe4ae-b90f-446a-960b-d6ce50904548</version_id>
<version_modified>2026-04-24T14:58:06Z</version_modified>
<xml_checksum>D8922A73</xml_checksum>
<class_name>HPXMLToOpenStudio</class_name>
<display_name>HPXML to OpenStudio Translator</display_name>
Expand Down Expand Up @@ -235,7 +235,7 @@
<filename>constants.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>6430B8D3</checksum>
<checksum>F541060C</checksum>
</file>
<file>
<filename>constructions.rb</filename>
Expand Down Expand Up @@ -433,7 +433,7 @@
<filename>hvac.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>E2717720</checksum>
<checksum>0BC8B241</checksum>
</file>
<file>
<filename>hvac_sizing.rb</filename>
Expand Down Expand Up @@ -499,7 +499,7 @@
<filename>output.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>2712B090</checksum>
<checksum>C04ABCAC</checksum>
</file>
<file>
<filename>psychrometrics.rb</filename>
Expand Down Expand Up @@ -673,7 +673,7 @@
<filename>schedules.rb</filename>
<filetype>rb</filetype>
<usage_type>resource</usage_type>
<checksum>DF514BC5</checksum>
<checksum>3E26C217</checksum>
</file>
<file>
<filename>simcontrols.rb</filename>
Expand Down Expand Up @@ -781,7 +781,7 @@
<filename>test_hvac.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>81FB2648</checksum>
<checksum>E770DC36</checksum>
</file>
<file>
<filename>test_hvac_sizing.rb</filename>
Expand Down Expand Up @@ -829,7 +829,7 @@
<filename>test_validation.rb</filename>
<filetype>rb</filetype>
<usage_type>test</usage_type>
<checksum>D9C6506E</checksum>
<checksum>FD24774E</checksum>
</file>
<file>
<filename>test_vehicle.rb</filename>
Expand Down
2 changes: 2 additions & 0 deletions HPXMLtoOpenStudio/resources/constants.rb
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,9 @@ module Constants
ObjectTypeMiscWellPump = 'misc well pump'
ObjectTypeNaturalVentilation = 'natural vent'
ObjectTypeNeighbors = 'neighbors'
ObjectTypeOATDrybulbSensor = 'outdoor air drybulb temperature sensor'
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is used for both defrost and crankcase.

ObjectTypeOccupants = 'occupants'
ObjectTypeCrankcaseHeater = 'crankcase heater'
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This is the new "end use" for actuated other equipment objects.

ObjectTypePanHeater = 'pan heater'
ObjectTypePhotovoltaics = 'photovoltaics'
ObjectTypePTAC = 'packaged terminal air conditioner'
Expand Down
204 changes: 183 additions & 21 deletions HPXMLtoOpenStudio/resources/hvac.rb

Large diffs are not rendered by default.

45 changes: 14 additions & 31 deletions HPXMLtoOpenStudio/resources/output.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1589,7 +1589,7 @@ def self.create_custom_unit_meters(model, hpxml)
model.getModelObjects.sort.each do |object|
next if object.to_AdditionalProperties.is_initialized

vars_by_key = get_object_outputs_by_key(model, object, EUT)
vars_by_key = get_object_outputs_by_key(object, EUT)
vars_by_key.each do |key, output_vars|
ft, eut = key

Expand Down Expand Up @@ -1648,7 +1648,7 @@ def self.get_object_outputs_for_hpxml_system(model, sys_id, eut_filter = nil)
next unless obj_id.is_initialized
next if sys_id != obj_id.get

vars_by_key = get_object_outputs_by_key(model, object, EUT)
vars_by_key = get_object_outputs_by_key(object, EUT)
vars_by_key.each do |key, object_vars|
if eut_filter.nil? || eut_filter.include?(key[1])
vars[key] = {} if vars[key].nil?
Expand All @@ -1663,11 +1663,10 @@ def self.get_object_outputs_for_hpxml_system(model, sys_id, eut_filter = nil)
# For a given object, returns the Output:Variables or Output:Meters to be requested,
# and associates them with the appropriate keys (e.g., [FT::Elec, EUT::Heating]).
#
# @param model [OpenStudio::Model::Model] OpenStudio Model object
# @param object [OpenStudio::Model::Foo] A given object in the OpenStudio Model
# @param class_type [Module] The output class type
# @return [Hash] Map of output key => array of EnergyPlus output variable/meter names
def self.get_object_outputs_by_key(model, object, class_type)
def self.get_object_outputs_by_key(object, class_type)
object_type = object.additionalProperties.getFeatureAsString('ObjectType')
object_type = object_type.get if object_type.is_initialized

Expand All @@ -1680,13 +1679,6 @@ def self.get_object_outputs_by_key(model, object, class_type)

if object.to_CoilHeatingDXSingleSpeed.is_initialized || object.to_CoilHeatingDXMultiSpeed.is_initialized
vars = { [FT::Elec, EUT::Heating] => ['Heating Coil Electricity Energy', 'Heating Coil Defrost Electricity Energy'] }
if object.additionalProperties.getFeatureAsDouble('FractionHeatLoadServed').is_initialized && object.additionalProperties.getFeatureAsDouble('FractionHeatLoadServed').get <= 0
# HP only provides cooling, allocate crankcase to cooling end use
vars[[FT::Elec, EUT::Cooling]] = ['Heating Coil Crankcase Heater Electricity Energy']
else
# Allocate crankcase to heating end use
vars[[FT::Elec, EUT::Heating]] << 'Heating Coil Crankcase Heater Electricity Energy'
end
Comment on lines -1683 to -1689
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

This allocation logic (and some below) is moved to the OtherEquipment block.

return vars

elsif object.to_CoilHeatingElectric.is_initialized || object.to_CoilHeatingElectricMultiStage.is_initialized
Expand Down Expand Up @@ -1733,26 +1725,7 @@ def self.get_object_outputs_by_key(model, object, class_type)
end

elsif object.to_CoilCoolingDXSingleSpeed.is_initialized || object.to_CoilCoolingDXMultiSpeed.is_initialized
vars = { [FT::Elec, EUT::Cooling] => ['Cooling Coil Electricity Energy'] }
parent = model.getAirLoopHVACUnitarySystems.select { |u| u.coolingCoil.is_initialized && u.coolingCoil.get.handle.to_s == object.handle.to_s }
Comment thread
joseph-robertson marked this conversation as resolved.
if (not parent.empty?) && parent[0].heatingCoil.is_initialized
htg_coil = parent[0].heatingCoil.get
end
if parent.empty?
parent = model.getZoneHVACPackagedTerminalAirConditioners.select { |u| u.coolingCoil.handle.to_s == object.handle.to_s }
if not parent.empty?
htg_coil = parent[0].heatingCoil
end
end
if parent.empty?
fail 'Could not find parent object.'
end

if htg_coil.nil? || (not (htg_coil.to_CoilHeatingDXSingleSpeed.is_initialized || htg_coil.to_CoilHeatingDXMultiSpeed.is_initialized))
# Crankcase variable only available if no DX heating coil on parent
vars[[FT::Elec, EUT::Cooling]] << 'Cooling Coil Crankcase Heater Electricity Energy'
end
return vars
return { [FT::Elec, EUT::Cooling] => ['Cooling Coil Electricity Energy'] }

elsif object.to_CoilCoolingWaterToAirHeatPumpEquationFit.is_initialized || object.to_CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.is_initialized
return { [FT::Elec, EUT::Cooling] => ['Cooling Coil Electricity Energy'] }
Expand Down Expand Up @@ -1864,6 +1837,7 @@ def self.get_object_outputs_by_key(model, object, class_type)
Constants::ObjectTypeMechanicalVentilationPreheating => EUT::MechVentPreheat,
Constants::ObjectTypeMechanicalVentilationPrecooling => EUT::MechVentPrecool,
Constants::ObjectTypeHPDefrostSupplHeat => EUT::HeatingHeatPumpBackup,
Constants::ObjectTypeCrankcaseHeater => [EUT::Heating, EUT::Cooling],
Constants::ObjectTypePanHeater => EUT::Heating,
Constants::ObjectTypeWaterHeaterAdjustment => EUT::HotWater,
Constants::ObjectTypeDSEHeating => EUT::Heating,
Expand All @@ -1876,6 +1850,15 @@ def self.get_object_outputs_by_key(model, object, class_type)
next unless subcategory.start_with? obj_name
fail "Unexpected error: multiple matches for #{eut}." unless end_use.nil?

if obj_name == Constants::ObjectTypeCrankcaseHeater
if object.additionalProperties.getFeatureAsDouble('FractionHeatLoadServed').get <= 0
# Allocate crankcase to cooling end use (cooling system or HP only provides cooling)
eut = eut[1]
else
eut = eut[0]
end
end

end_use = eut
end

Expand Down
4 changes: 1 addition & 3 deletions HPXMLtoOpenStudio/resources/schedules.rb
Original file line number Diff line number Diff line change
Expand Up @@ -822,9 +822,7 @@ def self.unavailable_period_applies(runner, schedule_name, col_name)
end
if applies == 1
if not runner.nil?
if [SchedulesFile::Columns[:SpaceHeating].name, SchedulesFile::Columns[:SpaceCooling].name].include?(schedule_name)
runner.registerWarning('It is not possible to eliminate all HVAC energy use (e.g. crankcase/defrost energy) in EnergyPlus during an unavailable period.')
elsif schedule_name == SchedulesFile::Columns[:WaterHeater].name
if schedule_name == SchedulesFile::Columns[:WaterHeater].name
runner.registerWarning('It is not possible to eliminate all DHW energy use (e.g. water heater parasitics) in EnergyPlus during an unavailable period.')
end
end
Expand Down
45 changes: 18 additions & 27 deletions HPXMLtoOpenStudio/tests/test_hvac.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1287,22 +1287,24 @@ def test_air_to_air_heat_pump_1_speed_onoff_thermostat
_check_onoff_thermostat_EMS(model, clg_coil, 1.0, 0.0, 0.0, 1.0, 0.0, 0.0)
end

def test_heat_pump_defrost_and_pan_heater
def test_heat_pump_defrost_and_pan_heater_and_crankcase_heater
Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Move the existing crankcase test into here since we're now, like defrost and pan heater, using EMS programs.

# Single Speed heat pump test
args_hash = {}
args_hash['hpxml_path'] = @tmp_hpxml_path
hpxml, hpxml_bldg = _create_hpxml('base-hvac-air-to-air-heat-pump-1-speed.xml')
hpxml_bldg.heat_pumps[0].pan_heater_watts = 60.0
hpxml_bldg.heat_pumps[0].crankcase_heater_watts = 20.0
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
model, _hpxml, hpxml_bldg = _test_measure(args_hash)

# Get HPXML values
backup_fuel = EPlus.fuel_type(hpxml_bldg.heat_pumps[0].backup_heating_fuel)
pan_heater_watts = hpxml_bldg.heat_pumps[0].pan_heater_watts
crankcase_heater_watts = hpxml_bldg.heat_pumps[0].crankcase_heater_watts

assert_equal(1, model.getCoilHeatingDXSingleSpeeds.size)
htg_coil = model.getCoilHeatingDXSingleSpeeds[0]
_check_defrost_and_pan_heater(model, htg_coil, 10000, 1.0, backup_fuel, 0.1, 0.0, pan_heater_watts)
_check_defrost_and_pan_heater_and_crankcase_heater(model, htg_coil, 10000, 1.0, backup_fuel, 0.1, 0.0, pan_heater_watts, crankcase_heater_watts)

# Ductless heat pump test
args_hash = {}
Expand All @@ -1314,7 +1316,7 @@ def test_heat_pump_defrost_and_pan_heater

assert_equal(1, model.getCoilHeatingDXMultiSpeeds.size)
htg_coil = model.getCoilHeatingDXMultiSpeeds[0]
_check_defrost_and_pan_heater(model, htg_coil, 0.0, 0.0, backup_fuel, 0.06667, 0.0)
_check_defrost_and_pan_heater_and_crankcase_heater(model, htg_coil, 0.0, 0.0, backup_fuel, 0.06667, 0.0)

# Ductless heat pump w/ backup heat during defrost test
args_hash = {}
Expand All @@ -1326,7 +1328,7 @@ def test_heat_pump_defrost_and_pan_heater

assert_equal(1, model.getCoilHeatingDXMultiSpeeds.size)
htg_coil = model.getCoilHeatingDXMultiSpeeds[0]
_check_defrost_and_pan_heater(model, htg_coil, 10000, 1.0, backup_fuel, 0.06667, 0.0)
_check_defrost_and_pan_heater_and_crankcase_heater(model, htg_coil, 10000, 1.0, backup_fuel, 0.06667, 0.0)

# Dual fuel heat pump test
args_hash = {}
Expand All @@ -1338,7 +1340,7 @@ def test_heat_pump_defrost_and_pan_heater

assert_equal(1, model.getCoilHeatingDXMultiSpeeds.size)
htg_coil = model.getCoilHeatingDXMultiSpeeds[0]
_check_defrost_and_pan_heater(model, htg_coil, 17584, 0.95, backup_fuel, 0.06667, 0.0)
_check_defrost_and_pan_heater_and_crankcase_heater(model, htg_coil, 17584, 0.95, backup_fuel, 0.06667, 0.0)

# Two heat pump test
args_hash = {}
Expand All @@ -1351,10 +1353,10 @@ def test_heat_pump_defrost_and_pan_heater

assert_equal(2, model.getCoilHeatingDXMultiSpeeds.size)
htg_coil = model.getCoilHeatingDXMultiSpeeds[0]
_check_defrost_and_pan_heater(model, htg_coil, 10000, 1.0, backup_fuel, 0.06667, 0.0, 150.0, 2)
_check_defrost_and_pan_heater_and_crankcase_heater(model, htg_coil, 10000, 1.0, backup_fuel, 0.06667, 0.0, 150.0, 30.0, 2)

htg_coil = model.getCoilHeatingDXMultiSpeeds[1]
_check_defrost_and_pan_heater(model, htg_coil, 10000, 1.0, backup_fuel, 0.06667, 0.0, 150.0, 2)
_check_defrost_and_pan_heater_and_crankcase_heater(model, htg_coil, 10000, 1.0, backup_fuel, 0.06667, 0.0, 150.0, 30.0, 2)

# Separate backup heat pump test
args_hash = {}
Expand All @@ -1366,7 +1368,7 @@ def test_heat_pump_defrost_and_pan_heater

assert_equal(1, model.getCoilHeatingDXMultiSpeeds.size)
htg_coil = model.getCoilHeatingDXMultiSpeeds[0]
_check_defrost_and_pan_heater(model, htg_coil, 0.0, 0.0, backup_fuel, 0.06667, 0.0)
_check_defrost_and_pan_heater_and_crankcase_heater(model, htg_coil, 0.0, 0.0, backup_fuel, 0.06667, 0.0, 150.0, 15.0)
end

def test_mini_split_heat_pump_ductless
Expand Down Expand Up @@ -2204,23 +2206,6 @@ def test_custom_seasons
assert_includes(end_dates, end_date)
end

def test_crankcase_heater_watts
args_hash = {}
args_hash['hpxml_path'] = @tmp_hpxml_path
hpxml, hpxml_bldg = _create_hpxml('base.xml')
hpxml_bldg.cooling_systems[0].crankcase_heater_watts = 40.0
XMLHelper.write_file(hpxml.to_doc, @tmp_hpxml_path)
model, _hpxml, hpxml_bldg = _test_measure(args_hash)

# Get HPXML values
cooling_system = hpxml_bldg.cooling_systems[0]
crankcase_heater_watts = cooling_system.crankcase_heater_watts

# Check cooling coil
clg_coil = model.getCoilCoolingDXSingleSpeeds[0]
assert_in_epsilon(crankcase_heater_watts, clg_coil.crankcaseHeaterCapacity, 0.01)
end

def test_ceiling_fan
args_hash = {}
args_hash['hpxml_path'] = File.absolute_path(File.join(@sample_files_path, 'base-lighting-ceiling-fans.xml'))
Expand Down Expand Up @@ -2435,7 +2420,7 @@ def _check_onoff_thermostat_EMS(model, clg_or_htg_coil, c1_cap, c2_cap, c3_cap,
return program_values
end

def _check_defrost_and_pan_heater(model, htg_coil, supp_capacity, supp_efficiency, backup_fuel, defrost_time_fraction, defrost_power, pan_heater_watts = 150.0, num_of_ems = 1)
def _check_defrost_and_pan_heater_and_crankcase_heater(model, htg_coil, supp_capacity, supp_efficiency, backup_fuel, defrost_time_fraction, defrost_power, pan_heater_watts = 150.0, crankcase_heater_watts = 30.0, num_of_ems = 1)
# Check Other equipment inputs
defrost_heat_load_oe = model.getOtherEquipments.select { |oe| oe.additionalProperties.getFeatureAsString('ObjectType').to_s == Constants::ObjectTypeHPDefrostHeatLoad }
assert_equal(num_of_ems, defrost_heat_load_oe.size)
Expand All @@ -2454,13 +2439,19 @@ def _check_defrost_and_pan_heater(model, htg_coil, supp_capacity, supp_efficienc
assert_in_epsilon(htg_coil.defrostTimePeriodFraction, defrost_time_fraction, 0.01)
assert_in_delta(htg_coil.resistiveDefrostHeaterCapacity.get, defrost_power, 1.0)

# Check EMS
# Check EMS defrost/pan heater
program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{htg_coil.name} defrost program")
assert_in_epsilon(program_values['supp_capacity'].sum, supp_capacity, 0.01)
assert_in_epsilon(program_values['supp_efficiency'].sum, supp_efficiency, 0.01)
pan_heater_act_name = program_values.keys.find { |k| k.include? 'pan_heater_energy_act' }
assert_equal(pan_heater_watts, program_values[pan_heater_act_name][0])
assert(!program_values.empty?)

# Check EMS crankcase heater
program_values = get_ems_values(model.getEnergyManagementSystemPrograms, "#{htg_coil.name} crankcase program")
crankcase_heater_act_name = program_values.keys.find { |k| k.include? 'crankcase_heater_energy_act' }
assert_equal(crankcase_heater_watts, program_values[crankcase_heater_act_name][0])
assert(!program_values.empty?)
end

def _check_ghp_standard(model, heat_pump, clg_cop, htg_cop, soil_density, soil_surface_temp_amps, phase_shift_temp_amps)
Expand Down
6 changes: 1 addition & 5 deletions HPXMLtoOpenStudio/tests/test_validation.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2026,7 +2026,6 @@ def test_ruby_warning_messages
'HPWH supply air ducted from another location is not currently supported; supply ducting will not be modeled.'],
'hpwh-small-containment-volume-without-backup-element' => ['Heat pump water heater: WaterHeatingSystem1 has no backup electric resistance element, COP adjustment for confined space may not be accurate when the containment space volume is below 450 cubic feet.'],
'hvac-gshp-bore-depth-autosized-high' => ['Reached a maximum of 10 boreholes; setting bore depth to the maximum (500 ft).'],
'hvac-seasons' => ['It is not possible to eliminate all HVAC energy use (e.g. crankcase/defrost energy) in EnergyPlus outside of an HVAC season.'],
'hvac-setpoint-adjustments' => ['HVAC setpoints have been automatically adjusted to prevent periods where the heating setpoint is greater than the cooling setpoint.'],
'hvac-setpoint-adjustments-daily-setbacks' => ['HVAC setpoints have been automatically adjusted to prevent periods where the heating setpoint is greater than the cooling setpoint.'],
'hvac-setpoint-adjustments-daily-schedules' => ['HVAC setpoints have been automatically adjusted to prevent periods where the heating setpoint is greater than the cooling setpoint.'],
Expand All @@ -2039,8 +2038,7 @@ def test_ruby_warning_messages
'multiple-inverter-efficiencies' => ['Inverters with varying efficiencies found; using a single PV size weighted-average in the model.'],
'panel-missing-default' => ["Voltage (240) for 'dishwasher' is not specified in default_panels.csv; PowerRating will be assigned according to Voltage=120.",
"Voltage (240) for 'dishwasher' is not specified in default_panels.csv; BreakerSpaces will be recalculated using Voltage=240."],
'power-outage' => ['It is not possible to eliminate all HVAC energy use (e.g. crankcase/defrost energy) in EnergyPlus during an unavailable period.',
'It is not possible to eliminate all DHW energy use (e.g. water heater parasitics) in EnergyPlus during an unavailable period.'],
'power-outage' => ['It is not possible to eliminate all DHW energy use (e.g. water heater parasitics) in EnergyPlus during an unavailable period.'],
'schedule-file-and-weekday-weekend-multipliers' => ["Both 'occupants' schedule file and weekday fractions provided; the latter will be ignored.",
"Both 'occupants' schedule file and weekend fractions provided; the latter will be ignored.",
"Both 'occupants' schedule file and monthly multipliers provided; the latter will be ignored.",
Expand Down Expand Up @@ -2207,8 +2205,6 @@ def test_ruby_warning_messages
when 'hvac-gshp-bore-depth-autosized-high'
hpxml, hpxml_bldg = _create_hpxml('base-hvac-ground-to-air-heat-pump-1-speed.xml')
hpxml_bldg.site.ground_conductivity = 0.07
when 'hvac-seasons'
hpxml, hpxml_bldg = _create_hpxml('base-hvac-seasons.xml')
when 'hvac-setpoint-adjustments'
hpxml, hpxml_bldg = _create_hpxml('base.xml')
hpxml_bldg.hvac_controls[0].heating_setpoint_temp = 76.0
Expand Down
Loading
Loading