urbanopt-cli 0.10.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (712) hide show
  1. checksums.yaml +4 -4
  2. data/.github/release.yml +24 -0
  3. data/.github/workflows/nightly_ci_build.yml +39 -29
  4. data/.gitignore +1 -0
  5. data/CHANGELOG.md +17 -0
  6. data/CMakeLists.txt +7 -7
  7. data/FindOpenStudioSDK.cmake +8 -8
  8. data/LICENSE.md +8 -35
  9. data/README.md +25 -10
  10. data/example_files/Gemfile +9 -9
  11. data/example_files/example_project_combined.json +6 -2
  12. data/example_files/example_project_with_ghe.json +859 -0
  13. data/example_files/mappers/Baseline.rb +39 -415
  14. data/example_files/mappers/ChilledWaterStorage.rb +1 -1
  15. data/example_files/mappers/CreateBar.rb +1 -1
  16. data/example_files/mappers/EvCharging.rb +1 -1
  17. data/example_files/mappers/FlexibleHotWater.rb +1 -1
  18. data/example_files/mappers/Floorspace.rb +1 -1
  19. data/example_files/mappers/HighEfficiency.rb +1 -1
  20. data/example_files/mappers/HighEfficiencyCreateBar.rb +1 -1
  21. data/example_files/mappers/HighEfficiencyFloorspace.rb +1 -1
  22. data/example_files/mappers/PeakHoursMelsShedding.rb +1 -1
  23. data/example_files/mappers/PeakHoursThermostatAdjust.rb +1 -1
  24. data/example_files/mappers/ThermalStorage.rb +1 -1
  25. data/example_files/mappers/base_workflow.osw +11 -4
  26. data/example_files/mappers/residential/template/util.rb +138 -0
  27. data/example_files/mappers/residential/util.rb +276 -0
  28. data/example_files/measures/BuildResidentialModel/measure.rb +118 -230
  29. data/example_files/measures/BuildResidentialModel/measure.xml +344 -233
  30. data/example_files/measures/BuildResidentialModel/resources/geometry.rb +7 -2
  31. data/example_files/measures/BuildResidentialModel/resources/unit_conversions.rb +5 -0
  32. data/example_files/measures/BuildResidentialModel/resources/util.rb +5 -0
  33. data/example_files/measures/BuildResidentialModel/tests/test_build_residential_model.rb +344 -0
  34. data/example_files/measures/BuildResidentialModel/tests/xml_building/17/feature1.xml +2112 -0
  35. data/example_files/measures/BuildResidentialModel/tests/xml_building/17/feature2.xml +2112 -0
  36. data/example_files/osm_building/7.osm +0 -2
  37. data/example_files/osm_building/8.osm +0 -2
  38. data/example_files/osm_building/9.osm +0 -2
  39. data/example_files/python_deps/dependencies.json +4 -3
  40. data/example_files/resources/hpxml-measures/.gitattributes +3 -0
  41. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +2 -2
  42. data/example_files/resources/hpxml-measures/.github/workflows/add_to_project.yml +17 -0
  43. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +37 -8
  44. data/example_files/resources/hpxml-measures/.gitignore +1 -0
  45. data/example_files/resources/hpxml-measures/.readthedocs.yml +6 -2
  46. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/README.md +5596 -0
  47. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/README.md.erb +41 -0
  48. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +1324 -1035
  49. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +325 -236
  50. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +119 -152
  51. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/{build_residential_hpxml_test.rb → test_build_residential_hpxml.rb} +225 -107
  52. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/README.md +96 -0
  53. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/README.md.erb +41 -0
  54. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.rb +73 -31
  55. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml +60 -40
  56. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/README.md +48 -23
  57. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/constants.rb +5 -0
  58. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb +6 -12
  59. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/tests/{build_residential_schedule_file_test.rb → test_build_residential_schedule_file.rb} +162 -35
  60. data/example_files/resources/hpxml-measures/Changelog.md +57 -1
  61. data/example_files/resources/hpxml-measures/Gemfile +1 -1
  62. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/README.md +83 -0
  63. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/README.md.erb +41 -0
  64. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +1081 -878
  65. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +258 -204
  66. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +205 -178
  67. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/battery.rb +43 -18
  68. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +37 -112
  69. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +34 -73
  70. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/Xing_okstate_0664D_13659_Table_A-3.csv +4165 -0
  71. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/unavailable_periods.csv +2 -2
  72. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +5 -1
  73. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/generator.rb +13 -7
  74. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +95 -42
  75. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +132 -108
  76. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +1695 -1267
  77. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +668 -589
  78. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXML.xsd +304 -553
  79. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml +197 -112
  80. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +1140 -1745
  81. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +412 -325
  82. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +56 -48
  83. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +49 -38
  84. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb +5 -0
  85. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +17 -1
  86. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/minitest_helper.rb +5 -0
  87. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +94 -78
  88. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/output.rb +60 -2
  89. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/psychrometrics.rb +6 -1
  90. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +11 -5
  91. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-non-stochastic.csv +1 -1
  92. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic-30-mins.csv +52561 -0
  93. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_2.csv +8761 -0
  94. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_3.csv +8761 -0
  95. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_4.csv +8761 -0
  96. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_5.csv +8761 -0
  97. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic_6.csv +8761 -0
  98. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +129 -137
  99. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +12 -21
  100. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/unit_conversions.rb +5 -0
  101. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/util.rb +7 -2
  102. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb +6 -1
  103. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +7 -2
  104. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +179 -144
  105. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/weather.rb +129 -71
  106. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +5 -0
  107. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlvalidator.rb +23 -6
  108. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +129 -118
  109. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_battery.rb +25 -20
  110. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +2282 -2239
  111. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +395 -204
  112. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +12 -7
  113. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +56 -51
  114. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +369 -230
  115. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +371 -191
  116. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +27 -20
  117. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +55 -5
  118. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +35 -30
  119. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +13 -8
  120. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_schedules.rb +107 -93
  121. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +11 -6
  122. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +757 -573
  123. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +77 -72
  124. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_weather.rb +36 -6
  125. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/util.rb +5 -0
  126. data/example_files/resources/hpxml-measures/README.md +2 -0
  127. data/example_files/resources/hpxml-measures/Rakefile +10 -3
  128. data/example_files/resources/hpxml-measures/ReportSimulationOutput/README.md +787 -0
  129. data/example_files/resources/hpxml-measures/ReportSimulationOutput/README.md.erb +41 -0
  130. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.rb +730 -418
  131. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.xml +1215 -9
  132. data/example_files/resources/hpxml-measures/ReportSimulationOutput/tests/{output_report_test.rb → test_report_sim_output.rb} +130 -299
  133. data/example_files/resources/hpxml-measures/ReportUtilityBills/README.md +87 -0
  134. data/example_files/resources/hpxml-measures/ReportUtilityBills/README.md.erb +41 -0
  135. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.rb +261 -89
  136. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.xml +179 -94
  137. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/Average_retail_price_of_electricity.csv +68 -68
  138. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/NG_PRI_SUM_A_EPG0_PRS_DMCF_A.csv +3 -2
  139. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/PET_PRI_WFR_A_EPD2F_PRS_DPGAL_W.csv +713 -685
  140. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/PET_PRI_WFR_A_EPLLPA_PRS_DPGAL_W.csv +716 -688
  141. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/simple_rates/README.md +5 -2
  142. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/util.rb +18 -9
  143. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/test_report_utility_bills.rb +1308 -0
  144. data/example_files/resources/hpxml-measures/docs/requirements.txt +5 -0
  145. data/example_files/resources/hpxml-measures/docs/source/conf.py +1 -2
  146. data/example_files/resources/hpxml-measures/docs/source/intro.rst +3 -20
  147. data/example_files/resources/hpxml-measures/docs/source/usage_instructions.rst +1 -1
  148. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +917 -564
  149. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +79 -42
  150. data/example_files/resources/hpxml-measures/tasks.rb +2305 -2055
  151. data/example_files/resources/hpxml-measures/workflow/hpxml_inputs.json +270 -587
  152. data/example_files/resources/hpxml-measures/workflow/real_homes/house001.xml +559 -557
  153. data/example_files/resources/hpxml-measures/workflow/real_homes/house002.xml +522 -520
  154. data/example_files/resources/hpxml-measures/workflow/real_homes/house003.xml +534 -532
  155. data/example_files/resources/hpxml-measures/workflow/real_homes/house004.xml +547 -545
  156. data/example_files/resources/hpxml-measures/workflow/real_homes/house005.xml +546 -544
  157. data/example_files/resources/hpxml-measures/workflow/real_homes/house006.xml +603 -623
  158. data/example_files/resources/hpxml-measures/workflow/real_homes/house007.xml +613 -633
  159. data/example_files/resources/hpxml-measures/workflow/real_homes/house008.xml +699 -721
  160. data/example_files/resources/hpxml-measures/workflow/real_homes/house009.xml +662 -661
  161. data/example_files/resources/hpxml-measures/workflow/real_homes/house010.xml +657 -677
  162. data/example_files/resources/hpxml-measures/workflow/real_homes/house011.xml +470 -467
  163. data/example_files/resources/hpxml-measures/workflow/real_homes/house012.xml +441 -438
  164. data/example_files/resources/hpxml-measures/workflow/real_homes/house013.xml +468 -465
  165. data/example_files/resources/hpxml-measures/workflow/real_homes/house014.xml +469 -466
  166. data/example_files/resources/hpxml-measures/workflow/real_homes/house015.xml +468 -465
  167. data/example_files/resources/hpxml-measures/workflow/real_homes/house016.xml +717 -714
  168. data/example_files/resources/hpxml-measures/workflow/real_homes/house017.xml +647 -645
  169. data/example_files/resources/hpxml-measures/workflow/real_homes/house018.xml +569 -566
  170. data/example_files/resources/hpxml-measures/workflow/real_homes/house019.xml +602 -599
  171. data/example_files/resources/hpxml-measures/workflow/real_homes/house020.xml +630 -627
  172. data/example_files/resources/hpxml-measures/workflow/real_homes/house021.xml +776 -774
  173. data/example_files/resources/hpxml-measures/workflow/real_homes/house022.xml +670 -667
  174. data/example_files/resources/hpxml-measures/workflow/real_homes/house023.xml +632 -629
  175. data/example_files/resources/hpxml-measures/workflow/real_homes/house024.xml +731 -729
  176. data/example_files/resources/hpxml-measures/workflow/real_homes/house025.xml +672 -669
  177. data/example_files/resources/hpxml-measures/workflow/real_homes/house026.xml +667 -644
  178. data/example_files/resources/hpxml-measures/workflow/real_homes/house027.xml +646 -644
  179. data/example_files/resources/hpxml-measures/workflow/real_homes/house028.xml +690 -688
  180. data/example_files/resources/hpxml-measures/workflow/real_homes/house029.xml +701 -699
  181. data/example_files/resources/hpxml-measures/workflow/real_homes/house030.xml +637 -615
  182. data/example_files/resources/hpxml-measures/workflow/real_homes/house031.xml +690 -688
  183. data/example_files/resources/hpxml-measures/workflow/real_homes/house032.xml +557 -554
  184. data/example_files/resources/hpxml-measures/workflow/real_homes/house033.xml +534 -531
  185. data/example_files/resources/hpxml-measures/workflow/real_homes/house034.xml +636 -635
  186. data/example_files/resources/hpxml-measures/workflow/real_homes/house035.xml +616 -613
  187. data/example_files/resources/hpxml-measures/workflow/real_homes/house036.xml +601 -598
  188. data/example_files/resources/hpxml-measures/workflow/real_homes/house037.xml +581 -578
  189. data/example_files/resources/hpxml-measures/workflow/real_homes/house038.xml +624 -622
  190. data/example_files/resources/hpxml-measures/workflow/real_homes/house039.xml +584 -582
  191. data/example_files/resources/hpxml-measures/workflow/real_homes/house040.xml +631 -629
  192. data/example_files/resources/hpxml-measures/workflow/real_homes/house041.xml +922 -921
  193. data/example_files/resources/hpxml-measures/workflow/real_homes/house042.xml +855 -853
  194. data/example_files/resources/hpxml-measures/workflow/real_homes/house043.xml +739 -737
  195. data/example_files/resources/hpxml-measures/workflow/real_homes/house044.xml +798 -796
  196. data/example_files/resources/hpxml-measures/workflow/real_homes/house045.xml +696 -694
  197. data/example_files/resources/hpxml-measures/workflow/real_homes/house046.xml +487 -483
  198. data/example_files/resources/hpxml-measures/workflow/real_homes/house047.xml +443 -440
  199. data/example_files/resources/hpxml-measures/workflow/real_homes/house048.xml +688 -686
  200. data/example_files/resources/hpxml-measures/workflow/real_homes/house049.xml +722 -720
  201. data/example_files/resources/hpxml-measures/workflow/real_homes/house050.xml +619 -617
  202. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +13 -20
  203. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +9 -9
  204. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +11 -12
  205. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +11 -12
  206. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +12 -13
  207. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +11 -12
  208. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +9 -9
  209. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +9 -9
  210. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +4 -4
  211. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +9 -9
  212. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +9 -9
  213. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +9 -9
  214. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +11 -11
  215. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +10 -10
  216. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +9 -9
  217. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +10 -11
  218. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +9 -9
  219. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +8 -8
  220. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery-scheduled.xml +571 -569
  221. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery.xml +9 -9
  222. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml → base-bldgtype-mf-unit-adjacent-to-multifamily-buffer-space.xml} +5 -5
  223. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-multiple.xml → base-bldgtype-mf-unit-adjacent-to-multiple.xml} +17 -17
  224. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml → base-bldgtype-mf-unit-adjacent-to-non-freezing-space.xml} +5 -5
  225. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-other-heated-space.xml → base-bldgtype-mf-unit-adjacent-to-other-heated-space.xml} +5 -5
  226. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml → base-bldgtype-mf-unit-adjacent-to-other-housing-unit.xml} +5 -5
  227. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-infil-compartmentalization-test.xml → base-bldgtype-mf-unit-infil-compartmentalization-test.xml} +461 -461
  228. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-residents-1.xml → base-bldgtype-mf-unit-residents-1.xml} +453 -453
  229. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml → base-bldgtype-mf-unit-shared-boiler-chiller-baseboard.xml} +11 -11
  230. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml → base-bldgtype-mf-unit-shared-boiler-chiller-fan-coil-ducted.xml} +11 -11
  231. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml → base-bldgtype-mf-unit-shared-boiler-chiller-fan-coil.xml} +11 -11
  232. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-boiler-chiller-water-loop-heat-pump.xml} +11 -11
  233. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-boiler-cooling-tower-water-loop-heat-pump.xml} +11 -11
  234. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-baseboard.xml → base-bldgtype-mf-unit-shared-boiler-only-baseboard.xml} +11 -11
  235. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml → base-bldgtype-mf-unit-shared-boiler-only-fan-coil-ducted.xml} +11 -11
  236. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml → base-bldgtype-mf-unit-shared-boiler-only-fan-coil-eae.xml} +11 -11
  237. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-mf-unit-shared-boiler-only-fan-coil-fireplace-elec.xml +433 -0
  238. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml → base-bldgtype-mf-unit-shared-boiler-only-fan-coil.xml} +11 -11
  239. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-boiler-only-water-loop-heat-pump.xml} +11 -11
  240. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-chiller-only-baseboard.xml → base-bldgtype-mf-unit-shared-chiller-only-baseboard.xml} +11 -11
  241. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml → base-bldgtype-mf-unit-shared-chiller-only-fan-coil-ducted.xml} +11 -11
  242. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml → base-bldgtype-mf-unit-shared-chiller-only-fan-coil.xml} +11 -11
  243. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-chiller-only-water-loop-heat-pump.xml} +11 -11
  244. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml → base-bldgtype-mf-unit-shared-cooling-tower-only-water-loop-heat-pump.xml} +11 -11
  245. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-generator.xml → base-bldgtype-mf-unit-shared-generator.xml} +13 -13
  246. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml → base-bldgtype-mf-unit-shared-ground-loop-ground-to-air-heat-pump.xml} +13 -13
  247. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-laundry-room-multiple-water-heaters.xml → base-bldgtype-mf-unit-shared-laundry-room-multiple-water-heaters.xml} +480 -480
  248. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-laundry-room.xml → base-bldgtype-mf-unit-shared-laundry-room.xml} +10 -10
  249. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-mechvent-multiple.xml → base-bldgtype-mf-unit-shared-mechvent-multiple.xml} +15 -15
  250. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-mechvent-preconditioning.xml → base-bldgtype-mf-unit-shared-mechvent-preconditioning.xml} +13 -13
  251. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-mechvent.xml → base-bldgtype-mf-unit-shared-mechvent.xml} +13 -13
  252. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-pv.xml → base-bldgtype-mf-unit-shared-pv.xml} +13 -13
  253. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-water-heater-recirc.xml → base-bldgtype-mf-unit-shared-water-heater-recirc.xml} +13 -13
  254. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-shared-water-heater.xml → base-bldgtype-mf-unit-shared-water-heater.xml} +13 -13
  255. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily.xml → base-bldgtype-mf-unit.xml} +13 -13
  256. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-attached-2stories.xml → base-bldgtype-sfa-unit-2stories.xml} +610 -610
  257. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-attached-atticroof-cathedral.xml → base-bldgtype-sfa-unit-atticroof-cathedral.xml} +558 -558
  258. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-attached-infil-compartmentalization-test.xml → base-bldgtype-sfa-unit-infil-compartmentalization-test.xml} +610 -610
  259. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-attached.xml → base-bldgtype-sfa-unit.xml} +610 -610
  260. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +8 -8
  261. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +9 -9
  262. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +9 -9
  263. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +9 -9
  264. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +9 -9
  265. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +9 -9
  266. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +9 -9
  267. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +9 -9
  268. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +9 -9
  269. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-detailed-setpoints.xml +507 -505
  270. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +9 -9
  271. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +8 -8
  272. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +9 -9
  273. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +9 -9
  274. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +9 -9
  275. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +9 -9
  276. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +9 -9
  277. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +9 -9
  278. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +9 -9
  279. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +12 -10
  280. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +14 -14
  281. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +5 -5
  282. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +9 -9
  283. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +9 -9
  284. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +9 -9
  285. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +9 -9
  286. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +9 -9
  287. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +9 -9
  288. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +9 -9
  289. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +9 -9
  290. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +9 -9
  291. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +9 -9
  292. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +9 -9
  293. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +9 -9
  294. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-detailed-setpoints.xml +12 -10
  295. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +9 -9
  296. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +8 -8
  297. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef-fhr.xml +9 -9
  298. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +9 -9
  299. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +9 -9
  300. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-detailed-schedules.xml +13 -11
  301. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-operating-mode-heat-pump-only.xml +9 -9
  302. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +8 -8
  303. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +9 -9
  304. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +9 -9
  305. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +9 -9
  306. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +9 -9
  307. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified-detailed-occupancy-stochastic.xml +12 -10
  308. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified.xml +9 -9
  309. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +9 -9
  310. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +9 -9
  311. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-detailed-setpoints.xml +12 -10
  312. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +8 -8
  313. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +9 -9
  314. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +9 -9
  315. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +9 -9
  316. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +9 -9
  317. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +9 -9
  318. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +9 -9
  319. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +9 -9
  320. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +13 -14
  321. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +11 -11
  322. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +9 -9
  323. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +9 -9
  324. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +9 -9
  325. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +9 -9
  326. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-ceilingtypes.xml +576 -576
  327. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-floortypes.xml +519 -519
  328. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +4 -5
  329. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +9 -9
  330. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +9 -9
  331. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +9 -9
  332. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ela.xml +548 -548
  333. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +9 -9
  334. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +9 -9
  335. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-cfm.xml +551 -551
  336. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-orientations.xml +9 -9
  337. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +9 -9
  338. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +9 -9
  339. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-physical-properties.xml +9 -9
  340. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +9 -9
  341. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-storms.xml +9 -9
  342. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +9 -9
  343. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +10 -11
  344. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-thermal-mass.xml +9 -9
  345. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +19 -19
  346. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-natural-ventilation-availability.xml +555 -553
  347. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +9 -9
  348. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-physical-properties.xml +9 -9
  349. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading-seasons.xml +560 -558
  350. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading.xml +9 -9
  351. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-storms.xml +9 -9
  352. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +10 -10
  353. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +10 -11
  354. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-belly-wing-no-skirt.xml +496 -0
  355. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-belly-wing-skirt.xml +496 -0
  356. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +18 -18
  357. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-schedules-simple-power-outage-natvent-unavailable.xml → base-foundation-conditioned-basement-slab-insulation-full.xml} +552 -564
  358. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +9 -9
  359. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-wall-insulation.xml +555 -555
  360. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-crawlspace.xml +8 -8
  361. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +5 -5
  362. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +10 -11
  363. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +4 -4
  364. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +4 -4
  365. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +4 -4
  366. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +4 -4
  367. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +9 -9
  368. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace-above-grade.xml +558 -0
  369. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +9 -9
  370. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +15 -15
  371. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +9 -9
  372. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-capacity-17f.xml +552 -552
  373. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +9 -9
  374. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-lockout-temperatures.xml +562 -562
  375. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-seer2-hspf2.xml +557 -557
  376. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +9 -9
  377. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +9 -9
  378. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-hvac-seasons.xml +586 -586
  379. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-switchover-temperature.xml +9 -9
  380. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml +9 -9
  381. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-furnace.xml +9 -9
  382. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-acca.xml → base-hvac-air-to-air-heat-pump-var-speed-detailed-performance-other-temperatures.xml} +89 -13
  383. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-hers.xml → base-hvac-air-to-air-heat-pump-var-speed-detailed-performance.xml} +107 -13
  384. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +9 -9
  385. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-sizing-controls.xml +567 -565
  386. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize.xml +9 -9
  387. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +9 -9
  388. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +9 -9
  389. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +9 -9
  390. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only-pilot.xml +512 -512
  391. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +9 -9
  392. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +9 -9
  393. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +9 -9
  394. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +9 -9
  395. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed-seer2.xml +536 -536
  396. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +9 -9
  397. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +9 -9
  398. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-central-ac-only-var-speed.xml → base-hvac-central-ac-only-var-speed-detailed-performance.xml} +49 -10
  399. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +9 -9
  400. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +9 -9
  401. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +9 -9
  402. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-lockout-temperatures.xml +559 -559
  403. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +9 -9
  404. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +9 -9
  405. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +9 -9
  406. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +9 -9
  407. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-fractions.xml +11 -12
  408. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-multipliers.xml +558 -558
  409. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-buried.xml +554 -554
  410. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-furnace-gas-room-ac.xml → base-hvac-ducts-defaults.xml} +28 -14
  411. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-effective-rvalue.xml +552 -552
  412. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-cfm50.xml +9 -9
  413. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +9 -9
  414. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +9 -9
  415. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +9 -9
  416. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +9 -9
  417. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +9 -9
  418. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +9 -9
  419. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +15 -10
  420. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +9 -9
  421. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +9 -9
  422. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +9 -9
  423. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +9 -9
  424. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +9 -9
  425. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-detailed-setpoints.xml +12 -10
  426. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-pilot.xml +541 -541
  427. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +9 -9
  428. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +9 -9
  429. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +9 -9
  430. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +9 -9
  431. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +9 -9
  432. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +9 -9
  433. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +9 -9
  434. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +9 -9
  435. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +9 -9
  436. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml +9 -9
  437. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml +9 -9
  438. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-air-to-air-heat-pump-1-speed-autosized-backup.xml → base-hvac-install-quality-air-to-air-heat-pump-var-speed-detailed-performance.xml} +650 -556
  439. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-var-speed.xml +9 -9
  440. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-1-speed.xml +9 -9
  441. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-2-speed.xml +9 -9
  442. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-var-speed.xml +9 -9
  443. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-only.xml +9 -9
  444. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-ground-to-air-heat-pump.xml +9 -9
  445. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-air-conditioner-only-ducted.xml +9 -9
  446. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-heat-pump-ducted.xml +9 -9
  447. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +9 -9
  448. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml → base-hvac-mini-split-air-conditioner-only-ductless-detailed-performance.xml} +50 -49
  449. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +9 -9
  450. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +9 -9
  451. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-maxload.xml → base-hvac-mini-split-heat-pump-ducted-detailed-performance.xml} +109 -14
  452. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +9 -9
  453. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +9 -9
  454. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-baseboard.xml +524 -524
  455. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted-backup-hardsized.xml → base-hvac-mini-split-heat-pump-ductless-backup-furnace-ducts-defaults.xml} +560 -552
  456. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-furnace.xml +563 -563
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-stove.xml +9 -9
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted.xml → base-hvac-mini-split-heat-pump-ductless-detailed-performance.xml} +108 -60
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-heating-capacity-17f.xml +505 -505
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +9 -9
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +9 -9
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +10 -11
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-electricity.xml +9 -9
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-natural-gas.xml +504 -504
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac.xml +9 -9
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp-heating-capacity-17f.xml +512 -512
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp.xml +9 -9
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +9 -9
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-ceer.xml +9 -9
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-detailed-setpoints.xml +12 -10
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +9 -9
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-heating.xml +504 -504
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-reverse-cycle.xml +517 -517
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-seasons.xml +9 -9
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-schedules.xml +9 -9
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-setbacks.xml +9 -9
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +9 -9
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-fixed-heater-gas-only.xml → base-hvac-space-heater-gas-only.xml} +10 -10
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +9 -9
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +9 -9
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +9 -9
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +9 -9
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +9 -9
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-holiday.xml +9 -9
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-kwh-per-year.xml +531 -528
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-mixed.xml +536 -536
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none-ceiling-fans.xml +515 -515
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +9 -9
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +9 -9
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +9 -9
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-capetown-zaf.xml +9 -9
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +10 -11
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +4 -4
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +9 -9
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +10 -11
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +10 -11
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +10 -11
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +9 -9
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +9 -9
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +9 -9
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-airflow-fraction-zero.xml +9 -9
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +9 -9
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +9 -9
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-exhaust.xml +576 -576
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-supply.xml +576 -576
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +9 -9
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +9 -9
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +9 -9
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +9 -9
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +9 -9
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +9 -9
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +9 -9
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +9 -9
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +9 -9
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +9 -9
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-additional-properties.xml +21 -19
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-detailed-only.xml +605 -605
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-mixed.xml +587 -587
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv.xml +9 -9
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills.xml +9 -9
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +3 -3
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-emissions.xml +9 -9
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery-scheduled.xml +587 -585
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery.xml +584 -584
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +9 -9
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-ground-conductivity.xml +555 -555
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +26 -26
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +26 -26
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +9 -9
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading-bldgtype-multifamily.xml +508 -508
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +9 -9
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +9 -9
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-schedules-simple-power-outage-natvent-available.xml → base-misc-unit-multiplier.xml} +553 -564
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +26 -26
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-mf-units.xml +2755 -0
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-multiple-buildings.xml → base-multiple-sfd-buildings.xml} +31 -22
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-ah.xml +9 -9
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-garage.xml +4 -5
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-round-trip-efficiency.xml +597 -597
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-scheduled.xml +599 -597
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery.xml +9 -9
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery-scheduled.xml +615 -613
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery.xml +612 -612
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators.xml +596 -596
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +9 -9
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-0-runperiod-1-month.xml +559 -559
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-0.xml +555 -555
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-1-misc-loads-large-uncommon.xml +616 -616
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-1-misc-loads-large-uncommon2.xml +616 -616
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-1.xml +547 -547
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-5.xml +515 -515
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-all-10-mins.xml +14 -12
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-crankcase-heater-40w.xml → base-schedules-detailed-mixed-timesteps-power-outage.xml} +565 -555
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-schedules-detailed-occupancy-stochastic-vacancy-year-round.xml → base-schedules-detailed-mixed-timesteps.xml} +554 -563
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-10-mins.xml +12 -10
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-power-outage.xml +566 -564
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-vacancy.xml +12 -10
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic.xml +12 -10
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-schedules.xml +12 -10
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-setbacks.xml +12 -10
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints.xml +12 -10
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-power-outage.xml +619 -619
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-vacancy.xml +618 -618
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple.xml +9 -9
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +9 -9
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +9 -9
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +9 -9
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +9 -9
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-temperature-capacitance-multiplier.xml +553 -553
  570. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-10-mins.xml +12 -10
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-60-mins.xml +12 -10
  572. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +9 -9
  573. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-30-mins.xml +552 -552
  574. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +9 -9
  575. data/example_files/resources/hpxml-measures/workflow/template-build-and-run-hpxml-with-stochastic-occupancy.osw +2 -0
  576. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy-subset.osw +2 -0
  577. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy.osw +2 -0
  578. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml.osw +4 -1
  579. data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Long_Residence.xml +385 -385
  580. data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Vatilo_Residence.xml +378 -380
  581. data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Victor_Residence.xml +369 -369
  582. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +7 -7
  583. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +7 -7
  584. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +7 -7
  585. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +7 -7
  586. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +7 -7
  587. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +7 -7
  588. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +7 -7
  589. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +7 -7
  590. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +7 -7
  591. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +7 -7
  592. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +7 -7
  593. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +7 -7
  594. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +7 -7
  595. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +7 -7
  596. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +7 -7
  597. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +7 -7
  598. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +7 -7
  599. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +7 -7
  600. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +7 -7
  601. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +7 -7
  602. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +7 -7
  603. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +7 -7
  604. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +7 -8
  605. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +7 -8
  606. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +6 -6
  607. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +6 -6
  608. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_sizing.csv +363 -0
  609. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_workflow_simulations1.csv +281 -0
  610. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_workflow_simulations1_bills.csv +281 -0
  611. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_workflow_simulations2.csv +141 -0
  612. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_workflow_simulations2_bills.csv +141 -0
  613. data/example_files/resources/hpxml-measures/workflow/tests/compare.py +12 -6
  614. data/example_files/resources/hpxml-measures/workflow/tests/util.rb +1141 -0
  615. data/example_files/weather/USA_CO_Denver.Intl.AP.725650_TMY3.ddy +536 -0
  616. data/example_files/weather/USA_CO_Denver.Intl.AP.725650_TMY3.epw +8768 -0
  617. data/example_files/weather/USA_CO_Denver.Intl.AP.725650_TMY3.stat +554 -0
  618. data/example_files/weather/USA_FL_MacDill.AFB.747880_TMY3.ddy +536 -0
  619. data/example_files/weather/USA_FL_MacDill.AFB.747880_TMY3.epw +8768 -0
  620. data/example_files/weather/USA_FL_MacDill.AFB.747880_TMY3.stat +553 -0
  621. data/example_files/weather/USA_GA_Atlanta-Hartsfield-Jackson.Intl.AP.722190_TMY3-cache.csv +35 -0
  622. data/example_files/weather/USA_GA_Atlanta-Hartsfield-Jackson.Intl.AP.722190_TMY3.ddy +536 -0
  623. data/example_files/weather/USA_GA_Atlanta-Hartsfield-Jackson.Intl.AP.722190_TMY3.epw +8768 -0
  624. data/example_files/weather/USA_GA_Atlanta-Hartsfield-Jackson.Intl.AP.722190_TMY3.stat +553 -0
  625. data/example_files/weather/USA_NY_Buffalo-Greater.Buffalo.Intl.AP.725280_TMY3-cache.csv +35 -0
  626. data/example_files/xml_building/17/README.md +4 -2
  627. data/example_files/xml_building/17/feature.xml +2112 -0
  628. data/lib/uo_cli/version.rb +1 -1
  629. data/lib/uo_cli.rb +110 -17
  630. data/uo_cli.gemspec +6 -8
  631. metadata +130 -177
  632. data/Jenkinsfile +0 -10
  633. data/example_files/base_workflow_res.osw +0 -276
  634. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/utility_bills_test.rb +0 -1226
  635. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil-location-miami-fl.xml +0 -551
  636. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane-location-portland-or.xml +0 -551
  637. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +0 -544
  638. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +0 -550
  639. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +0 -552
  640. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +0 -552
  641. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload-miami-fl.xml +0 -552
  642. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +0 -552
  643. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-acca.xml +0 -552
  644. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-hers.xml +0 -552
  645. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-maxload.xml +0 -552
  646. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler.xml +0 -569
  647. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-furnace.xml +0 -599
  648. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-maxload.xml +0 -552
  649. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-elec-only.xml +0 -506
  650. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-central-ac-1-speed.xml +0 -560
  651. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-only.xml +0 -507
  652. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-1-speed.xml +0 -536
  653. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-2-speed.xml +0 -536
  654. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-plus-air-to-air-heat-pump-heating.xml +0 -565
  655. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +0 -553
  656. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +0 -553
  657. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +0 -553
  658. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-elec-resistance-only.xml +0 -497
  659. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-evap-cooler-furnace-gas.xml +0 -544
  660. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-floor-furnace-propane-only.xml +0 -500
  661. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-elec-only.xml +0 -536
  662. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-2-speed.xml +0 -551
  663. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-var-speed.xml +0 -551
  664. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +0 -536
  665. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +0 -546
  666. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +0 -552
  667. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-acca.xml +0 -554
  668. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-hers.xml +0 -554
  669. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-maxload.xml +0 -554
  670. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-cooling-only.xml +0 -543
  671. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-heating-only.xml +0 -549
  672. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-acca.xml +0 -551
  673. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-hers.xml +0 -551
  674. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-baseboard.xml +0 -519
  675. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-stove.xml +0 -522
  676. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac-with-heating.xml +0 -503
  677. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac.xml +0 -496
  678. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-acca.xml +0 -518
  679. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-hers.xml +0 -518
  680. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-maxload.xml +0 -518
  681. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-only.xml +0 -496
  682. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-heating.xml +0 -503
  683. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-acca.xml +0 -518
  684. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-hers.xml +0 -518
  685. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-maxload.xml +0 -518
  686. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-stove-oil-only.xml +0 -500
  687. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-wall-furnace-elec-only.xml +0 -500
  688. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only-pilot-light.xml +0 -506
  689. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +0 -501
  690. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +0 -556
  691. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-none.xml +0 -548
  692. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-vacancy-year-round.xml +0 -619
  693. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +0 -475
  694. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_bills.csv +0 -475
  695. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +0 -1313
  696. data/example_files/resources/measure-info.json +0 -26
  697. data/example_files/resources/meta_measure.rb +0 -301
  698. data/example_files/xml_building/17/unit 1.xml +0 -580
  699. data/example_files/xml_building/17/unit 2.xml +0 -553
  700. data/example_files/xml_building/17/unit 3.xml +0 -553
  701. data/example_files/xml_building/17/unit 4.xml +0 -580
  702. /data/example_files/{residential → mappers/residential/template/iecc}/clothes_dryer.tsv +0 -0
  703. /data/example_files/{residential → mappers/residential/template/iecc}/clothes_washer.tsv +0 -0
  704. /data/example_files/{residential → mappers/residential/template/iecc}/cooling_system.tsv +0 -0
  705. /data/example_files/{residential → mappers/residential/template/iecc}/dishwasher.tsv +0 -0
  706. /data/example_files/{residential → mappers/residential/template/iecc}/enclosure.tsv +0 -0
  707. /data/example_files/{residential → mappers/residential/template/iecc}/heat_pump.tsv +0 -0
  708. /data/example_files/{residential → mappers/residential/template/iecc}/heating_system.tsv +0 -0
  709. /data/example_files/{residential → mappers/residential/template/iecc}/mechanical_ventilation.tsv +0 -0
  710. /data/example_files/{residential → mappers/residential/template/iecc}/refrigerator.tsv +0 -0
  711. /data/example_files/{residential → mappers/residential/template/iecc}/water_heater.tsv +0 -0
  712. /data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/{JacksonElectricMemberCorp-ResidentialSeniorCitizenLowIncomeAssistance.json → Detailed Rate.json} +0 -0
@@ -0,0 +1,1141 @@
1
+ # *********************************************************************************
2
+ # URBANopt (tm), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://github.com/urbanopt/urbanopt-cli/blob/develop/LICENSE.md
4
+ # *********************************************************************************
5
+
6
+ # frozen_string_literal: true
7
+
8
+ def run_simulation_tests(xmls)
9
+ # Run simulations
10
+ puts "Running #{xmls.size} HPXML files..."
11
+ all_results = {}
12
+ all_results_bills = {}
13
+ Parallel.map(xmls, in_threads: Parallel.processor_count) do |xml|
14
+ next if xml.end_with? '-10x.xml'
15
+ next if xml.include? 'base-multiple-sfd-buildings' # Separate tests cover this
16
+ next if xml.include? 'base-multiple-mf-units' # Separate tests cover this
17
+
18
+ xml_name = File.basename(xml)
19
+ results = _run_xml(xml, Parallel.worker_number)
20
+ all_results[xml_name], all_results_bills[xml_name], timeseries_results = results
21
+
22
+ next unless xml.include?('sample_files') || xml.include?('real_homes')
23
+
24
+ # Also run with a 10x unit multiplier (2 identical dwelling units each with a 5x
25
+ # unit multiplier) and check how the results compare to the original run
26
+ _run_xml(xml, Parallel.worker_number, true, all_results[xml_name], timeseries_results)
27
+ end
28
+
29
+ return all_results, all_results_bills
30
+ end
31
+
32
+ def _run_xml(xml, worker_num, apply_unit_multiplier = false, results_1x = nil, timeseries_results_1x = nil)
33
+ unit_multiplier = 1
34
+ if apply_unit_multiplier
35
+ hpxml = HPXML.new(hpxml_path: xml, building_id: 'ALL')
36
+ hpxml.buildings.each do |hpxml_bldg|
37
+ next unless hpxml_bldg.building_construction.number_of_units.nil?
38
+
39
+ hpxml_bldg.building_construction.number_of_units = 1
40
+ end
41
+ orig_multiplier = hpxml.buildings.map { |hpxml_bldg| hpxml_bldg.building_construction.number_of_units }.sum
42
+
43
+ # Create copy of the HPXML where the number of Building elements is doubled
44
+ # and each Building is assigned a unit multiplier of 5 (2x5=10).
45
+ n_bldgs = hpxml.buildings.size
46
+ for i in 0..n_bldgs - 1
47
+ hpxml_bldg = hpxml.buildings[i]
48
+ if hpxml_bldg.dehumidifiers.size > 0
49
+ # FUTURE: Dehumidifiers currently don't give desired results w/ unit multipliers
50
+ # https://github.com/NREL/OpenStudio-HPXML/issues/1499
51
+ elsif hpxml_bldg.heat_pumps.select { |hp| hp.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir }.size > 0
52
+ # FUTURE: GSHPs currently don't give desired results w/ unit multipliers
53
+ # https://github.com/NREL/OpenStudio-HPXML/issues/1499
54
+ elsif hpxml_bldg.batteries.size > 0
55
+ # FUTURE: Batteries currently don't work with whole SFA/MF buildings
56
+ # https://github.com/NREL/OpenStudio-HPXML/issues/1499
57
+ return
58
+ else
59
+ hpxml_bldg.building_construction.number_of_units *= 5
60
+ end
61
+ hpxml.buildings << hpxml_bldg.dup
62
+ end
63
+ xml.gsub!('.xml', '-10x.xml')
64
+ hpxml_doc = hpxml.to_doc()
65
+ hpxml.set_unique_hpxml_ids(hpxml_doc)
66
+ XMLHelper.write_file(hpxml_doc, xml)
67
+ unit_multiplier = hpxml.buildings.map { |hpxml_bldg| hpxml_bldg.building_construction.number_of_units }.sum / orig_multiplier
68
+ end
69
+
70
+ print "Testing #{File.basename(xml)}...\n"
71
+ rundir = File.join(File.dirname(__FILE__), "test#{worker_num}")
72
+
73
+ # Uses 'monthly' to verify timeseries results match annual results via error-checking
74
+ # inside the ReportSimulationOutput measure.
75
+ cli_path = OpenStudio.getOpenStudioCLI
76
+ command = "\"#{cli_path}\" \"#{File.join(File.dirname(__FILE__), '../run_simulation.rb')}\" -x \"#{xml}\" --add-component-loads -o \"#{rundir}\" --debug --monthly ALL"
77
+ if unit_multiplier > 1
78
+ command += ' -b ALL'
79
+ end
80
+ success = system(command)
81
+
82
+ if unit_multiplier > 1
83
+ # Clean up
84
+ File.delete(xml)
85
+ xml.gsub!('-10x.xml', '.xml')
86
+ end
87
+
88
+ rundir = File.join(rundir, 'run')
89
+
90
+ # Check results
91
+ print "Simulation failed: #{xml}.\n" unless success
92
+ assert_equal(true, success)
93
+
94
+ # Check for output files
95
+ annual_csv_path = File.join(rundir, 'results_annual.csv')
96
+ timeseries_csv_path = File.join(rundir, 'results_timeseries.csv')
97
+ bills_csv_path = File.join(rundir, 'results_bills.csv')
98
+ assert(File.exist? annual_csv_path)
99
+ assert(File.exist? timeseries_csv_path)
100
+
101
+ # Check outputs
102
+ hpxml_defaults_path = File.join(rundir, 'in.xml')
103
+ schema_validator = XMLValidator.get_schema_validator(File.join(File.dirname(__FILE__), '..', '..', 'HPXMLtoOpenStudio', 'resources', 'hpxml_schema', 'HPXML.xsd'))
104
+ schematron_validator = XMLValidator.get_schematron_validator(File.join(File.dirname(__FILE__), '..', '..', 'HPXMLtoOpenStudio', 'resources', 'hpxml_schematron', 'EPvalidator.xml'))
105
+ hpxml = HPXML.new(hpxml_path: hpxml_defaults_path, schema_validator: schema_validator, schematron_validator: schematron_validator, building_id: 'ALL') # Validate in.xml to ensure it can be run back through OS-HPXML
106
+ if not hpxml.errors.empty?
107
+ puts 'ERRORS:'
108
+ hpxml.errors.each do |error|
109
+ puts error
110
+ end
111
+ flunk "EPvalidator.xml error in #{hpxml_defaults_path}."
112
+ end
113
+ bill_results = _get_bill_results(bills_csv_path)
114
+ results = _get_simulation_results(annual_csv_path)
115
+ timeseries_results = _get_simulation_timeseries_results(timeseries_csv_path)
116
+ _verify_outputs(rundir, xml, results, hpxml, unit_multiplier)
117
+ if unit_multiplier > 1
118
+ _check_unit_multiplier_results(hpxml.buildings[0], results_1x, results, timeseries_results_1x, timeseries_results, unit_multiplier)
119
+ end
120
+
121
+ return results, bill_results, timeseries_results
122
+ end
123
+
124
+ def _get_simulation_results(annual_csv_path)
125
+ # Grab all outputs from reporting measure CSV annual results
126
+ results = {}
127
+ CSV.foreach(annual_csv_path) do |row|
128
+ next if row.nil? || (row.size < 2)
129
+
130
+ results[row[0]] = Float(row[1])
131
+ end
132
+
133
+ return results
134
+ end
135
+
136
+ def _get_simulation_timeseries_results(timeseries_csv_path)
137
+ results = {}
138
+ headers = nil
139
+ CSV.foreach(timeseries_csv_path).with_index do |row, i|
140
+ row = row[1..-1] # Skip time column
141
+ if i == 0 # Header row
142
+ headers = row
143
+ next
144
+ elsif i == 1 # Units row
145
+ headers = headers.zip(row).map { |header, units| "#{header} (#{units})" }
146
+ next
147
+ end
148
+
149
+ for i in 0..row.size - 1
150
+ results[headers[i]] = [] if results[headers[i]].nil?
151
+ results[headers[i]] << Float(row[i])
152
+ end
153
+ end
154
+
155
+ return results
156
+ end
157
+
158
+ def _get_bill_results(bill_csv_path)
159
+ # Grab all outputs (except monthly) from reporting measure CSV bill results
160
+ results = {}
161
+ if File.exist? bill_csv_path
162
+ CSV.foreach(bill_csv_path) do |row|
163
+ next if row.nil? || (row.size < 2)
164
+ next if (1..12).to_a.any? { |month| row[0].include?(": Month #{month}:") }
165
+
166
+ results[row[0]] = Float(row[1])
167
+ end
168
+ end
169
+
170
+ return results
171
+ end
172
+
173
+ def _verify_outputs(rundir, hpxml_path, results, hpxml, unit_multiplier)
174
+ assert(File.exist? File.join(rundir, 'eplusout.msgpack'))
175
+
176
+ hpxml_header = hpxml.header
177
+ hpxml_bldg = hpxml.buildings[0]
178
+ sqlFile = OpenStudio::SqlFile.new(File.join(rundir, 'eplusout.sql'), false)
179
+
180
+ # Collapse windows further using same logic as measure.rb
181
+ hpxml_bldg.windows.each do |window|
182
+ window.fraction_operable = nil
183
+ end
184
+ hpxml_bldg.collapse_enclosure_surfaces()
185
+ hpxml_bldg.delete_adiabatic_subsurfaces()
186
+
187
+ # Check run.log warnings
188
+ File.readlines(File.join(rundir, 'run.log')).each do |message|
189
+ next if message.strip.empty?
190
+ next if message.start_with? 'Info: '
191
+ next if message.start_with? 'Executing command'
192
+ next if message.include? 'Could not find state average'
193
+
194
+ if hpxml_bldg.clothes_washers.empty?
195
+ next if message.include? 'No clothes washer specified, the model will not include clothes washer energy use.'
196
+ end
197
+ if hpxml_bldg.clothes_dryers.empty?
198
+ next if message.include? 'No clothes dryer specified, the model will not include clothes dryer energy use.'
199
+ end
200
+ if hpxml_bldg.dishwashers.empty?
201
+ next if message.include? 'No dishwasher specified, the model will not include dishwasher energy use.'
202
+ end
203
+ if hpxml_bldg.refrigerators.empty?
204
+ next if message.include? 'No refrigerator specified, the model will not include refrigerator energy use.'
205
+ end
206
+ if hpxml_bldg.cooking_ranges.empty?
207
+ next if message.include? 'No cooking range specified, the model will not include cooking range/oven energy use.'
208
+ end
209
+ if hpxml_bldg.water_heating_systems.empty?
210
+ next if message.include? 'No water heating specified, the model will not include water heating energy use.'
211
+ end
212
+ if (hpxml_bldg.heating_systems + hpxml_bldg.heat_pumps).select { |h| h.fraction_heat_load_served.to_f > 0 }.empty?
213
+ next if message.include? 'No space heating specified, the model will not include space heating energy use.'
214
+ end
215
+ if (hpxml_bldg.cooling_systems + hpxml_bldg.heat_pumps).select { |c| c.fraction_cool_load_served.to_f > 0 }.empty?
216
+ next if message.include? 'No space cooling specified, the model will not include space cooling energy use.'
217
+ end
218
+ if hpxml_bldg.plug_loads.select { |p| p.plug_load_type == HPXML::PlugLoadTypeOther }.empty?
219
+ next if message.include? "No '#{HPXML::PlugLoadTypeOther}' plug loads specified, the model will not include misc plug load energy use."
220
+ end
221
+ if hpxml_bldg.plug_loads.select { |p| p.plug_load_type == HPXML::PlugLoadTypeTelevision }.empty?
222
+ next if message.include? "No '#{HPXML::PlugLoadTypeTelevision}' plug loads specified, the model will not include television plug load energy use."
223
+ end
224
+ if hpxml_bldg.lighting_groups.empty?
225
+ next if message.include? 'No interior lighting specified, the model will not include interior lighting energy use.'
226
+ next if message.include? 'No exterior lighting specified, the model will not include exterior lighting energy use.'
227
+ next if message.include? 'No garage lighting specified, the model will not include garage lighting energy use.'
228
+ end
229
+ if hpxml_bldg.windows.empty?
230
+ next if message.include? 'No windows specified, the model will not include window heat transfer.'
231
+ end
232
+ if hpxml_bldg.pv_systems.empty? && !hpxml_bldg.batteries.empty? && hpxml_bldg.header.schedules_filepaths.empty?
233
+ next if message.include? 'Battery without PV specified, and no charging/discharging schedule provided; battery is assumed to operate as backup and will not be modeled.'
234
+ end
235
+ if hpxml_path.include? 'base-location-capetown-zaf.xml'
236
+ next if message.include? 'OS Message: Minutes field (60) on line 9 of EPW file'
237
+ next if message.include? 'Could not find a marginal Electricity rate.'
238
+ next if message.include? 'Could not find a marginal Natural Gas rate.'
239
+ end
240
+ if !hpxml_bldg.hvac_distributions.select { |d| d.distribution_system_type == HPXML::HVACDistributionTypeDSE }.empty?
241
+ next if message.include? 'DSE is not currently supported when calculating utility bills.'
242
+ end
243
+ if !hpxml_header.unavailable_periods.select { |up| up.column_name == 'Power Outage' }.empty?
244
+ next if message.include? 'It is not possible to eliminate all HVAC energy use (e.g. crankcase/defrost energy) in EnergyPlus during an unavailable period.'
245
+ next if message.include? 'It is not possible to eliminate all water heater energy use (e.g. parasitics) in EnergyPlus during an unavailable period.'
246
+ end
247
+ if hpxml_path.include? 'base-location-AMY-2012.xml'
248
+ next if message.include? 'No design condition info found; calculating design conditions from EPW weather data.'
249
+ end
250
+ if hpxml_bldg.building_construction.number_of_units > 1
251
+ next if message.include? 'NumberofUnits is greater than 1, indicating that the HPXML Building represents multiple dwelling units; simulation outputs will reflect this unit multiplier.'
252
+ end
253
+
254
+ # FUTURE: Revert this eventually
255
+ # https://github.com/NREL/OpenStudio-HPXML/issues/1499
256
+ if hpxml_header.utility_bill_scenarios.has_detailed_electric_rates
257
+ uses_unit_multipliers = hpxml.buildings.select { |hpxml_bldg| hpxml_bldg.building_construction.number_of_units > 1 }.size > 0
258
+ if uses_unit_multipliers || hpxml.buildings.size > 1
259
+ next if message.include? 'Cannot currently calculate utility bills based on detailed electric rates for an HPXML with unit multipliers or multiple Building elements'
260
+ end
261
+ end
262
+
263
+ flunk "Unexpected run.log message found for #{File.basename(hpxml_path)}: #{message}"
264
+ end
265
+
266
+ # Check for unexpected eplusout.err messages
267
+ messages = []
268
+ message = nil
269
+ File.readlines(File.join(rundir, 'eplusout.err')).each do |err_line|
270
+ if err_line.include?('** Warning **') || err_line.include?('** Severe **') || err_line.include?('** Fatal **')
271
+ messages << message unless message.nil?
272
+ message = err_line
273
+ else
274
+ message += err_line unless message.nil?
275
+ end
276
+ end
277
+
278
+ messages.each do |message|
279
+ # General
280
+ next if message.include? 'Schedule:Constant="ALWAYS ON CONTINUOUS", Blank Schedule Type Limits Name input'
281
+ next if message.include? 'Schedule:Constant="ALWAYS ON DISCRETE", Blank Schedule Type Limits Name input'
282
+ next if message.include? 'Schedule:Constant="ALWAYS OFF DISCRETE", Blank Schedule Type Limits Name input'
283
+ next if message.include? 'Entered Zone Volumes differ from calculated zone volume'
284
+ next if message.include? 'PerformancePrecisionTradeoffs: Carroll MRT radiant exchange method is selected.'
285
+ next if message.include?('CalculateZoneVolume') && message.include?('not fully enclosed')
286
+ next if message.include? 'do not define an enclosure'
287
+ next if message.include? 'Pump nominal power or motor efficiency is set to 0'
288
+ next if message.include? 'volume flow rate per watt of rated total cooling capacity is out of range'
289
+ next if message.include? 'volume flow rate per watt of rated total heating capacity is out of range'
290
+ next if message.include? 'The Standard Ratings is calculated for'
291
+ next if message.include?('WetBulb not converged after') && message.include?('iterations(PsyTwbFnTdbWPb)')
292
+ next if message.include? 'Inside surface heat balance did not converge with Max Temp Difference'
293
+ next if message.include? 'Inside surface heat balance convergence problem continues'
294
+ next if message.include?('Glycol: Temperature') && message.include?('out of range (too low) for fluid')
295
+ next if message.include?('Glycol: Temperature') && message.include?('out of range (too high) for fluid')
296
+ next if message.include? 'Plant loop exceeding upper temperature limit'
297
+ next if message.include? 'Plant loop falling below lower temperature limit'
298
+ next if message.include?('Foundation:Kiva') && message.include?('wall surfaces with more than four vertices') # TODO: Check alternative approach
299
+ next if message.include? 'Temperature out of range [-100. to 200.] (PsyPsatFnTemp)'
300
+ next if message.include? 'Enthalpy out of range (PsyTsatFnHPb)'
301
+ next if message.include? 'Full load outlet air dry-bulb temperature < 2C. This indicates the possibility of coil frost/freeze.'
302
+ next if message.include? 'Full load outlet temperature indicates a possibility of frost/freeze error continues.'
303
+ next if message.include? 'Air-cooled condenser inlet dry-bulb temperature below 0 C.'
304
+ next if message.include? 'Low condenser dry-bulb temperature error continues.'
305
+ next if message.include? 'Coil control failed'
306
+ next if message.include? 'sensible part-load ratio out of range error continues'
307
+ next if message.include? 'Iteration limit exceeded in calculating sensible part-load ratio error continues'
308
+ next if message.include?('setupIHGOutputs: Output variables=Zone Other Equipment') && message.include?('are not available.')
309
+ next if message.include?('setupIHGOutputs: Output variables=Space Other Equipment') && message.include?('are not available')
310
+ next if message.include? 'Multiple speed fan will be applied to this unit. The speed number is determined by load.'
311
+
312
+ # HPWHs
313
+ if hpxml_bldg.water_heating_systems.select { |wh| wh.water_heater_type == HPXML::WaterHeaterTypeHeatPump }.size > 0
314
+ next if message.include? 'Recovery Efficiency and Energy Factor could not be calculated during the test for standard ratings'
315
+ next if message.include? 'SimHVAC: Maximum iterations (20) exceeded for all HVAC loops'
316
+ next if message.include? 'Rated air volume flow rate per watt of rated total water heating capacity is out of range'
317
+ next if message.include? 'For object = Coil:WaterHeating:AirToWaterHeatPump:Wrapped'
318
+ next if message.include? 'Enthalpy out of range (PsyTsatFnHPb)'
319
+ next if message.include?('CheckWarmupConvergence: Loads Initialization') && message.include?('did not converge after 25 warmup days')
320
+ end
321
+ # HPWHs outside
322
+ if hpxml_bldg.water_heating_systems.select { |wh| wh.water_heater_type == HPXML::WaterHeaterTypeHeatPump && wh.location == HPXML::LocationOtherExterior }.size > 0
323
+ next if message.include? 'Water heater tank set point temperature is greater than or equal to the cut-in temperature of the heat pump water heater.'
324
+ end
325
+ # Stratified tank WHs
326
+ if hpxml_bldg.water_heating_systems.select { |wh| wh.tank_model_type == HPXML::WaterHeaterTankModelTypeStratified }.size > 0
327
+ next if message.include? 'Recovery Efficiency and Energy Factor could not be calculated during the test for standard ratings'
328
+ end
329
+ # HP defrost curves
330
+ if hpxml_bldg.heat_pumps.select { |hp| [HPXML::HVACTypeHeatPumpAirToAir, HPXML::HVACTypeHeatPumpMiniSplit, HPXML::HVACTypeHeatPumpPTHP, HPXML::HVACTypeHeatPumpRoom].include? hp.heat_pump_type }.size > 0
331
+ next if message.include?('GetDXCoils: Coil:Heating:DX') && message.include?('curve values') && message.include?('Defrost Energy Input Ratio Function of Temperature Curve')
332
+ end
333
+ # variable system SHR adjustment
334
+ if (hpxml_bldg.heat_pumps + hpxml_bldg.cooling_systems).select { |hp| hp.compressor_type == HPXML::HVACCompressorTypeVariableSpeed }.size > 0
335
+ next if message.include?('CalcCBF: SHR adjusted to achieve valid outlet air properties and the simulation continues.')
336
+ end
337
+ # Evaporative coolers
338
+ if hpxml_bldg.cooling_systems.select { |c| c.cooling_system_type == HPXML::HVACTypeEvaporativeCooler }.size > 0
339
+ # Evap cooler model is not really using Controller:MechanicalVentilation object, so these warnings of ignoring some features are fine.
340
+ # OS requires a Controller:MechanicalVentilation to be attached to the oa controller, however it's not required by E+.
341
+ # Manually removing Controller:MechanicalVentilation from idf eliminates these two warnings.
342
+ # FUTURE: Can we update OS to allow removing it?
343
+ next if message.include?('Zone') && message.include?('is not accounted for by Controller:MechanicalVentilation object')
344
+ next if message.include?('PEOPLE object for zone') && message.include?('is not accounted for by Controller:MechanicalVentilation object')
345
+ # "The only valid controller type for an AirLoopHVAC is Controller:WaterCoil.", evap cooler doesn't need one.
346
+ next if message.include?('GetAirPathData: AirLoopHVAC') && message.include?('has no Controllers')
347
+ # input "Autosize" for Fixed Minimum Air Flow Rate is added by OS translation, now set it to 0 to skip potential sizing process, though no way to prevent this warning.
348
+ next if message.include? 'Since Zone Minimum Air Flow Input Method = CONSTANT, input for Fixed Minimum Air Flow Rate will be ignored'
349
+ end
350
+ # Fan coil distribution
351
+ if hpxml_bldg.hvac_distributions.select { |d| d.air_type.to_s == HPXML::AirTypeFanCoil }.size > 0
352
+ next if message.include? 'In calculating the design coil UA for Coil:Cooling:Water' # Warning for unused cooling coil for fan coil
353
+ end
354
+ # Boilers
355
+ if hpxml_bldg.heating_systems.select { |h| h.heating_system_type == HPXML::HVACTypeBoiler }.size > 0
356
+ next if message.include? 'Missing temperature setpoint for LeavingSetpointModulated mode' # These warnings are fine, simulation continues with assigning plant loop setpoint to boiler, which is the expected one
357
+ end
358
+ # GSHPs
359
+ if hpxml_bldg.heat_pumps.select { |hp| hp.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir }.size > 0
360
+ next if message.include?('CheckSimpleWAHPRatedCurvesOutputs') && message.include?('WaterToAirHeatPump:EquationFit') # FUTURE: Check these
361
+ next if message.include? 'Actual air mass flow rate is smaller than 25% of water-to-air heat pump coil rated air flow rate.' # FUTURE: Remove this when https://github.com/NREL/EnergyPlus/issues/9125 is resolved
362
+ end
363
+ # GSHPs with only heating or cooling
364
+ if hpxml_bldg.heat_pumps.select { |hp| hp.heat_pump_type == HPXML::HVACTypeHeatPumpGroundToAir && (hp.fraction_heat_load_served == 0 || hp.fraction_cool_load_served == 0) }.size > 0
365
+ next if message.include? 'heating capacity is disproportionate (> 20% different) to total cooling capacity' # safe to ignore
366
+ end
367
+ # Solar thermal systems
368
+ if hpxml_bldg.solar_thermal_systems.size > 0
369
+ next if message.include? 'Supply Side is storing excess heat the majority of the time.'
370
+ end
371
+ # Unavailability periods
372
+ if !hpxml_header.unavailable_periods.empty?
373
+ next if message.include? 'Target water temperature is greater than the hot water temperature'
374
+ next if message.include? 'Target water temperature should be less than or equal to the hot water temperature'
375
+ end
376
+ # Simulation w/ timesteps longer than 15-minutes
377
+ timestep = hpxml_header.timestep.nil? ? 60 : hpxml_header.timestep
378
+ if timestep > 15
379
+ next if message.include?('Timestep: Requested number') && message.include?('is less than the suggested minimum')
380
+ end
381
+ # TODO: Check why this house produces this warning
382
+ if hpxml_path.include? 'house044.xml'
383
+ next if message.include? 'FixViewFactors: View factors not complete. Check for bad surface descriptions or unenclosed zone'
384
+ end
385
+
386
+ flunk "Unexpected eplusout.err message found for #{File.basename(hpxml_path)}: #{message}"
387
+ end
388
+
389
+ # Check for unused objects/schedules/constructions warnings
390
+ num_unused_objects = 0
391
+ num_unused_schedules = 0
392
+ num_unused_constructions = 0
393
+ File.readlines(File.join(rundir, 'eplusout.err')).each do |err_line|
394
+ if err_line.include? 'unused objects in input'
395
+ num_unused_objects = Integer(err_line.split(' ')[3])
396
+ elsif err_line.include? 'unused schedules in input'
397
+ num_unused_schedules = Integer(err_line.split(' ')[3])
398
+ elsif err_line.include? 'unused constructions in input'
399
+ num_unused_constructions = Integer(err_line.split(' ')[6])
400
+ end
401
+ end
402
+ assert_equal(0, num_unused_objects)
403
+ assert_equal(0, num_unused_schedules)
404
+ assert_equal(0, num_unused_constructions)
405
+
406
+ # Check for Output:Meter and Output:Variable warnings
407
+ num_invalid_output_meters = 0
408
+ num_invalid_output_variables = 0
409
+ File.readlines(File.join(rundir, 'eplusout.err')).each do |err_line|
410
+ if err_line.include? 'Output:Meter: invalid Key Name'
411
+ num_invalid_output_meters += 1
412
+ elsif err_line.include?('Key=') && err_line.include?('VarName=')
413
+ num_invalid_output_variables += 1
414
+ end
415
+ end
416
+ assert_equal(0, num_invalid_output_meters)
417
+ assert_equal(0, num_invalid_output_variables)
418
+
419
+ # Check discrepancy between total load and sum of component loads
420
+ if not hpxml_path.include? 'ASHRAE_Standard_140'
421
+ sum_component_htg_loads = results.select { |k, _v| k.start_with? 'Component Load: Heating:' }.values.sum(0.0)
422
+ sum_component_clg_loads = results.select { |k, _v| k.start_with? 'Component Load: Cooling:' }.values.sum(0.0)
423
+ total_htg_load_delivered = results['Load: Heating: Delivered (MBtu)']
424
+ total_clg_load_delivered = results['Load: Cooling: Delivered (MBtu)']
425
+ abs_htg_load_delta = (total_htg_load_delivered - sum_component_htg_loads).abs
426
+ abs_clg_load_delta = (total_clg_load_delivered - sum_component_clg_loads).abs
427
+ avg_htg_load = [total_htg_load_delivered, sum_component_htg_loads].sum / 2.0
428
+ avg_clg_load = [total_clg_load_delivered, sum_component_clg_loads].sum / 2.0
429
+ if avg_htg_load > 0
430
+ abs_htg_load_frac = abs_htg_load_delta / avg_htg_load
431
+ end
432
+ if avg_clg_load > 0
433
+ abs_clg_load_frac = abs_clg_load_delta / avg_clg_load
434
+ end
435
+ # Check that the difference is less than 1.5 MBtu or less than 10%
436
+ assert((abs_htg_load_delta < 1.5 * unit_multiplier) || (!abs_htg_load_frac.nil? && abs_htg_load_frac < 0.1))
437
+ assert((abs_clg_load_delta < 1.5 * unit_multiplier) || (!abs_clg_load_frac.nil? && abs_clg_load_frac < 0.1))
438
+ end
439
+
440
+ return if (hpxml.buildings.size > 1) || (hpxml_bldg.building_construction.number_of_units > 1)
441
+
442
+ # Timestep
443
+ timestep = hpxml_header.timestep.nil? ? 60 : hpxml_header.timestep
444
+ query = 'SELECT NumTimestepsPerHour FROM Simulations'
445
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
446
+ assert_equal(60 / timestep, sql_value)
447
+
448
+ # Conditioned Floor Area
449
+ if (hpxml_bldg.total_fraction_cool_load_served > 0) || (hpxml_bldg.total_fraction_heat_load_served > 0) # EnergyPlus will only report conditioned floor area if there is an HVAC system
450
+ hpxml_value = hpxml_bldg.building_construction.conditioned_floor_area
451
+ if hpxml_bldg.has_location(HPXML::LocationCrawlspaceConditioned)
452
+ hpxml_value += hpxml_bldg.slabs.select { |s| s.interior_adjacent_to == HPXML::LocationCrawlspaceConditioned }.map { |s| s.area }.sum
453
+ end
454
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='InputVerificationandResultsSummary' AND ReportForString='Entire Facility' AND TableName='Zone Summary' AND RowName='Conditioned Total' AND ColumnName='Area' AND Units='m2'"
455
+ sql_value = UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'm^2', 'ft^2')
456
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
457
+ end
458
+
459
+ # Enclosure Roofs
460
+ hpxml_bldg.roofs.each do |roof|
461
+ roof_id = roof.id.upcase
462
+
463
+ # R-value
464
+ hpxml_value = roof.insulation_assembly_r_value
465
+ if hpxml_path.include? 'ASHRAE_Standard_140'
466
+ # Compare R-value w/o film
467
+ hpxml_value -= Material.AirFilmRoofASHRAE140.rvalue
468
+ hpxml_value -= Material.AirFilmOutsideASHRAE140.rvalue
469
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='Opaque Exterior' AND (RowName='#{roof_id}' OR RowName LIKE '#{roof_id}:%') AND ColumnName='U-Factor no Film' AND Units='W/m2-K'"
470
+ else
471
+ # Compare R-value w/ film
472
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='Opaque Exterior' AND (RowName='#{roof_id}' OR RowName LIKE '#{roof_id}:%') AND ColumnName='U-Factor with Film' AND Units='W/m2-K'"
473
+ end
474
+ sql_value = 1.0 / UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'W/(m^2*K)', 'Btu/(hr*ft^2*F)')
475
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
476
+
477
+ # Net area
478
+ hpxml_value = roof.area
479
+ hpxml_bldg.skylights.each do |subsurface|
480
+ next if subsurface.roof_idref.upcase != roof_id
481
+
482
+ hpxml_value -= subsurface.area
483
+ end
484
+ query = "SELECT SUM(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='Opaque Exterior' AND (RowName='#{roof_id}' OR RowName LIKE '#{roof_id}:%') AND ColumnName='Net Area' AND Units='m2'"
485
+ sql_value = UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'm^2', 'ft^2')
486
+ assert_operator(sql_value, :>, 0.01)
487
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
488
+
489
+ # Solar absorptance
490
+ hpxml_value = roof.solar_absorptance
491
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='Opaque Exterior' AND (RowName='#{roof_id}' OR RowName LIKE '#{roof_id}:%') AND ColumnName='Reflectance'"
492
+ sql_value = 1.0 - sqlFile.execAndReturnFirstDouble(query).get
493
+ assert_in_epsilon(hpxml_value, sql_value, 0.01)
494
+
495
+ # Tilt
496
+ hpxml_value = UnitConversions.convert(Math.atan(roof.pitch / 12.0), 'rad', 'deg')
497
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='Opaque Exterior' AND (RowName='#{roof_id}' OR RowName LIKE '#{roof_id}:%') AND ColumnName='Tilt' AND Units='deg'"
498
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
499
+ assert_in_epsilon(hpxml_value, sql_value, 0.01)
500
+
501
+ # Azimuth
502
+ next unless (not roof.azimuth.nil?) && (Float(roof.pitch) > 0)
503
+
504
+ hpxml_value = roof.azimuth
505
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='Opaque Exterior' AND (RowName='#{roof_id}' OR RowName LIKE '#{roof_id}:%') AND ColumnName='Azimuth' AND Units='deg'"
506
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
507
+ assert_in_epsilon(hpxml_value, sql_value, 0.01)
508
+ end
509
+
510
+ # Enclosure Foundations
511
+ # Ensure Kiva instances have perimeter fraction of 1.0 as we explicitly define them to end up this way.
512
+ num_kiva_instances = 0
513
+ File.readlines(File.join(rundir, 'eplusout.eio')).each do |eio_line|
514
+ next unless eio_line.downcase.start_with? 'foundation kiva'
515
+
516
+ kiva_perim_frac = Float(eio_line.split(',')[5])
517
+ assert_equal(1.0, kiva_perim_frac)
518
+
519
+ num_kiva_instances += 1
520
+ end
521
+
522
+ # Enclosure Foundation Slabs
523
+ num_slabs = hpxml_bldg.slabs.size
524
+ if (num_slabs <= 1) && (num_kiva_instances <= 1) # The slab surfaces may be combined in these situations, so skip tests
525
+ hpxml_bldg.slabs.each do |slab|
526
+ slab_id = slab.id.upcase
527
+
528
+ # Exposed Area
529
+ hpxml_value = Float(slab.area)
530
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='Opaque Exterior' AND RowName='#{slab_id}' AND ColumnName='Gross Area' AND Units='m2'"
531
+ sql_value = UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'm^2', 'ft^2')
532
+ assert_operator(sql_value, :>, 0.01)
533
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
534
+
535
+ # Tilt
536
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='Opaque Exterior' AND RowName='#{slab_id}' AND ColumnName='Tilt' AND Units='deg'"
537
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
538
+ assert_in_epsilon(180.0, sql_value, 0.01)
539
+ end
540
+ end
541
+
542
+ # Enclosure Walls/RimJoists/FoundationWalls
543
+ (hpxml_bldg.walls + hpxml_bldg.rim_joists + hpxml_bldg.foundation_walls).each do |wall|
544
+ wall_id = wall.id.upcase
545
+
546
+ if wall.is_adiabatic
547
+ # Adiabatic surfaces have their "BaseSurfaceIndex" as their "ExtBoundCond" in "Surfaces" table in SQL simulation results
548
+ query_base_surf_idx = "SELECT BaseSurfaceIndex FROM Surfaces WHERE SurfaceName='#{wall_id}'"
549
+ query_ext_bound = "SELECT ExtBoundCond FROM Surfaces WHERE SurfaceName='#{wall_id}'"
550
+ sql_value_base_surf_idx = sqlFile.execAndReturnFirstDouble(query_base_surf_idx).get
551
+ sql_value_ext_bound_cond = sqlFile.execAndReturnFirstDouble(query_ext_bound).get
552
+ assert_equal(sql_value_base_surf_idx, sql_value_ext_bound_cond)
553
+ end
554
+
555
+ if wall.is_exterior
556
+ table_name = 'Opaque Exterior'
557
+ else
558
+ table_name = 'Opaque Interior'
559
+ end
560
+
561
+ # R-value
562
+ if (not wall.insulation_assembly_r_value.nil?) && (not wall.is_a? HPXML::FoundationWall) # FoundationWalls use Foundation:Kiva for insulation
563
+ hpxml_value = wall.insulation_assembly_r_value
564
+ if hpxml_path.include? 'ASHRAE_Standard_140'
565
+ # Compare R-value w/o film
566
+ hpxml_value -= Material.AirFilmVerticalASHRAE140.rvalue
567
+ if wall.is_exterior
568
+ hpxml_value -= Material.AirFilmOutsideASHRAE140.rvalue
569
+ else
570
+ hpxml_value -= Material.AirFilmVerticalASHRAE140.rvalue
571
+ end
572
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND (RowName='#{wall_id}' OR RowName LIKE '#{wall_id}:%') AND ColumnName='U-Factor no Film' AND Units='W/m2-K'"
573
+ elsif wall.is_interior
574
+ # Compare R-value w/o film
575
+ hpxml_value -= Material.AirFilmVertical.rvalue
576
+ hpxml_value -= Material.AirFilmVertical.rvalue
577
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND (RowName='#{wall_id}' OR RowName LIKE '#{wall_id}:%') AND ColumnName='U-Factor no Film' AND Units='W/m2-K'"
578
+ else
579
+ # Compare R-value w/ film
580
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND (RowName='#{wall_id}' OR RowName LIKE '#{wall_id}:%') AND ColumnName='U-Factor with Film' AND Units='W/m2-K'"
581
+ end
582
+ sql_value = 1.0 / UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'W/(m^2*K)', 'Btu/(hr*ft^2*F)')
583
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
584
+ end
585
+
586
+ # Net area
587
+ hpxml_value = wall.net_area
588
+ if wall.is_a? HPXML::FoundationWall
589
+ if wall.is_exterior
590
+ # only modeling portion of foundation wall that is exposed perimeter
591
+ hpxml_value *= wall.exposed_fraction
592
+ else
593
+ # interzonal foundation walls: only above-grade portion modeled
594
+ hpxml_value *= (wall.height - wall.depth_below_grade) / wall.height
595
+ end
596
+ end
597
+ if wall.is_exterior
598
+ query = "SELECT SUM(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND (RowName='#{wall_id}' OR RowName LIKE '#{wall_id}:%' OR RowName LIKE '#{wall_id} %') AND ColumnName='Net Area' AND Units='m2'"
599
+ else
600
+ query = "SELECT SUM(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND (RowName='#{wall_id}' OR RowName LIKE '#{wall_id}:%') AND ColumnName='Net Area' AND Units='m2'"
601
+ end
602
+ sql_value = UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'm^2', 'ft^2')
603
+ assert_operator(sql_value, :>, 0.01)
604
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
605
+
606
+ # Solar absorptance
607
+ if wall.respond_to?(:solar_absorptance) && (not wall.solar_absorptance.nil?)
608
+ hpxml_value = wall.solar_absorptance
609
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND (RowName='#{wall_id}' OR RowName LIKE '#{wall_id}:%') AND ColumnName='Reflectance'"
610
+ sql_value = 1.0 - sqlFile.execAndReturnFirstDouble(query).get
611
+ assert_in_epsilon(hpxml_value, sql_value, 0.01)
612
+ end
613
+
614
+ # Tilt
615
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND (RowName='#{wall_id}' OR RowName LIKE '#{wall_id}:%') AND ColumnName='Tilt' AND Units='deg'"
616
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
617
+ assert_in_epsilon(90.0, sql_value, 0.01)
618
+
619
+ # Azimuth
620
+ next if wall.azimuth.nil?
621
+
622
+ hpxml_value = wall.azimuth
623
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND (RowName='#{wall_id}' OR RowName LIKE '#{wall_id}:%') AND ColumnName='Azimuth' AND Units='deg'"
624
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
625
+ assert_in_epsilon(hpxml_value, sql_value, 0.01)
626
+ end
627
+
628
+ # Enclosure Floors
629
+ hpxml_bldg.floors.each do |floor|
630
+ floor_id = floor.id.upcase
631
+
632
+ if floor.is_adiabatic
633
+ # Adiabatic surfaces have their "BaseSurfaceIndex" as their "ExtBoundCond" in "Surfaces" table in SQL simulation results
634
+ query_base_surf_idx = "SELECT BaseSurfaceIndex FROM Surfaces WHERE SurfaceName='#{floor_id}'"
635
+ query_ext_bound = "SELECT ExtBoundCond FROM Surfaces WHERE SurfaceName='#{floor_id}'"
636
+ sql_value_base_surf_idx = sqlFile.execAndReturnFirstDouble(query_base_surf_idx).get
637
+ sql_value_ext_bound_cond = sqlFile.execAndReturnFirstDouble(query_ext_bound).get
638
+ assert_equal(sql_value_base_surf_idx, sql_value_ext_bound_cond)
639
+ end
640
+
641
+ if floor.is_exterior
642
+ table_name = 'Opaque Exterior'
643
+ else
644
+ table_name = 'Opaque Interior'
645
+ end
646
+
647
+ # R-value
648
+ hpxml_value = floor.insulation_assembly_r_value
649
+ if hpxml_path.include? 'ASHRAE_Standard_140'
650
+ # Compare R-value w/o film
651
+ if floor.is_exterior # Raised floor
652
+ hpxml_value -= Material.AirFilmFloorASHRAE140.rvalue
653
+ hpxml_value -= Material.AirFilmFloorZeroWindASHRAE140.rvalue
654
+ elsif floor.is_ceiling # Attic floor
655
+ hpxml_value -= Material.AirFilmFloorASHRAE140.rvalue
656
+ hpxml_value -= Material.AirFilmFloorASHRAE140.rvalue
657
+ end
658
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{floor_id}' AND ColumnName='U-Factor no Film' AND Units='W/m2-K'"
659
+ elsif floor.is_interior
660
+ # Compare R-value w/o film
661
+ if floor.is_ceiling
662
+ hpxml_value -= Material.AirFilmFloorAverage.rvalue
663
+ hpxml_value -= Material.AirFilmFloorAverage.rvalue
664
+ else
665
+ hpxml_value -= Material.AirFilmFloorReduced.rvalue
666
+ hpxml_value -= Material.AirFilmFloorReduced.rvalue
667
+ end
668
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{floor_id}' AND ColumnName='U-Factor no Film' AND Units='W/m2-K'"
669
+ else
670
+ # Compare R-value w/ film
671
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{floor_id}' AND ColumnName='U-Factor with Film' AND Units='W/m2-K'"
672
+ end
673
+ sql_value = 1.0 / UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'W/(m^2*K)', 'Btu/(hr*ft^2*F)')
674
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
675
+
676
+ # Area
677
+ hpxml_value = floor.area
678
+ query = "SELECT SUM(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{floor_id}' AND ColumnName='Net Area' AND Units='m2'"
679
+ sql_value = UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'm^2', 'ft^2')
680
+ assert_operator(sql_value, :>, 0.01)
681
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
682
+
683
+ # Tilt
684
+ if floor.is_ceiling
685
+ hpxml_value = 0
686
+ else
687
+ hpxml_value = 180
688
+ end
689
+ query = "SELECT AVG(Value) FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{floor_id}' AND ColumnName='Tilt' AND Units='deg'"
690
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
691
+ assert_in_epsilon(hpxml_value, sql_value, 0.01)
692
+ end
693
+
694
+ # Enclosure Windows/Skylights
695
+ (hpxml_bldg.windows + hpxml_bldg.skylights).each do |subsurface|
696
+ subsurface_id = subsurface.id.upcase
697
+
698
+ if subsurface.is_exterior
699
+ table_name = 'Exterior Fenestration'
700
+ else
701
+ table_name = 'Interior Door'
702
+ end
703
+
704
+ # Area
705
+ if subsurface.is_exterior
706
+ col_name = 'Area of Multiplied Openings'
707
+ else
708
+ col_name = 'Gross Area'
709
+ end
710
+ hpxml_value = subsurface.area
711
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{subsurface_id}' AND ColumnName='#{col_name}' AND Units='m2'"
712
+ sql_value = UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'm^2', 'ft^2')
713
+ assert_operator(sql_value, :>, 0.01)
714
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
715
+
716
+ # U-Factor
717
+ if subsurface.is_exterior
718
+ col_name = 'Glass U-Factor'
719
+ else
720
+ col_name = 'U-Factor no Film'
721
+ end
722
+ hpxml_value = Constructions.get_ufactor_shgc_adjusted_by_storms(subsurface.storm_type, subsurface.ufactor, subsurface.shgc)[0]
723
+ if subsurface.is_interior
724
+ hpxml_value = 1.0 / (1.0 / hpxml_value - Material.AirFilmVertical.rvalue)
725
+ hpxml_value = 1.0 / (1.0 / hpxml_value - Material.AirFilmVertical.rvalue)
726
+ end
727
+ if subsurface.is_a? HPXML::Skylight
728
+ hpxml_value /= 1.2 # converted to the 20-deg slope from the vertical position by multiplying the tested value at vertical
729
+ end
730
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{subsurface_id}' AND ColumnName='#{col_name}' AND Units='W/m2-K'"
731
+ sql_value = UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'W/(m^2*K)', 'Btu/(hr*ft^2*F)')
732
+ assert_in_epsilon(hpxml_value, sql_value, 0.02)
733
+
734
+ next unless subsurface.is_exterior
735
+
736
+ # SHGC
737
+ hpxml_value = Constructions.get_ufactor_shgc_adjusted_by_storms(subsurface.storm_type, subsurface.ufactor, subsurface.shgc)[1]
738
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{subsurface_id}' AND ColumnName='Glass SHGC'"
739
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
740
+ assert_in_delta(hpxml_value, sql_value, 0.01)
741
+
742
+ # Azimuth
743
+ hpxml_value = subsurface.azimuth
744
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{subsurface_id}' AND ColumnName='Azimuth' AND Units='deg'"
745
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
746
+ assert_in_epsilon(hpxml_value, sql_value, 0.01)
747
+
748
+ # Tilt
749
+ if subsurface.is_a? HPXML::Window
750
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{subsurface_id}' AND ColumnName='Tilt' AND Units='deg'"
751
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
752
+ assert_in_epsilon(90.0, sql_value, 0.01)
753
+ elsif subsurface.is_a? HPXML::Skylight
754
+ hpxml_value = nil
755
+ hpxml_bldg.roofs.each do |roof|
756
+ next if roof.id != subsurface.roof_idref
757
+
758
+ hpxml_value = UnitConversions.convert(Math.atan(roof.pitch / 12.0), 'rad', 'deg')
759
+ end
760
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{subsurface_id}' AND ColumnName='Tilt' AND Units='deg'"
761
+ sql_value = sqlFile.execAndReturnFirstDouble(query).get
762
+ assert_in_epsilon(hpxml_value, sql_value, 0.01)
763
+ else
764
+ flunk "Subsurface '#{subsurface_id}' should have either AttachedToWall or AttachedToRoof element."
765
+ end
766
+ end
767
+
768
+ # Enclosure Doors
769
+ hpxml_bldg.doors.each do |door|
770
+ door_id = door.id.upcase
771
+
772
+ if door.wall.is_exterior
773
+ table_name = 'Exterior Door'
774
+ else
775
+ table_name = 'Interior Door'
776
+ end
777
+
778
+ # Area
779
+ if not door.area.nil?
780
+ hpxml_value = door.area
781
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{door_id}' AND ColumnName='Gross Area' AND Units='m2'"
782
+ sql_value = UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'm^2', 'ft^2')
783
+ assert_operator(sql_value, :>, 0.01)
784
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
785
+ end
786
+
787
+ # R-Value
788
+ next if door.r_value.nil?
789
+
790
+ if door.is_exterior
791
+ col_name = 'U-Factor with Film'
792
+ else
793
+ col_name = 'U-Factor no Film'
794
+ end
795
+ hpxml_value = door.r_value
796
+ if door.is_interior
797
+ hpxml_value -= Material.AirFilmVertical.rvalue
798
+ hpxml_value -= Material.AirFilmVertical.rvalue
799
+ end
800
+ query = "SELECT Value FROM TabularDataWithStrings WHERE ReportName='EnvelopeSummary' AND ReportForString='Entire Facility' AND TableName='#{table_name}' AND RowName='#{door_id}' AND ColumnName='#{col_name}' AND Units='W/m2-K'"
801
+ sql_value = 1.0 / UnitConversions.convert(sqlFile.execAndReturnFirstDouble(query).get, 'W/(m^2*K)', 'Btu/(hr*ft^2*F)')
802
+ assert_in_epsilon(hpxml_value, sql_value, 0.1)
803
+ end
804
+
805
+ # HVAC Load Fractions
806
+ if (not hpxml_path.include? 'location-miami') && (not hpxml_path.include? 'location-honolulu') && (not hpxml_path.include? 'location-phoenix')
807
+ htg_energy = results.select { |k, _v| (k.include?(': Heating (MBtu)') || k.include?(': Heating Fans/Pumps (MBtu)')) && !k.include?('Load') }.values.sum(0.0)
808
+ assert_equal(hpxml_bldg.total_fraction_heat_load_served > 0, htg_energy > 0)
809
+ end
810
+ clg_energy = results.select { |k, _v| (k.include?(': Cooling (MBtu)') || k.include?(': Cooling Fans/Pumps (MBtu)')) && !k.include?('Load') }.values.sum(0.0)
811
+ assert_equal(hpxml_bldg.total_fraction_cool_load_served > 0, clg_energy > 0)
812
+
813
+ # Mechanical Ventilation
814
+ whole_vent_fans = hpxml_bldg.ventilation_fans.select { |vent_mech| vent_mech.used_for_whole_building_ventilation && !vent_mech.is_cfis_supplemental_fan? }
815
+ local_vent_fans = hpxml_bldg.ventilation_fans.select { |vent_mech| vent_mech.used_for_local_ventilation }
816
+ fan_cfis = whole_vent_fans.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeCFIS }
817
+ fan_sup = whole_vent_fans.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeSupply }
818
+ fan_exh = whole_vent_fans.select { |vent_mech| vent_mech.fan_type == HPXML::MechVentTypeExhaust }
819
+ fan_bal = whole_vent_fans.select { |vent_mech| [HPXML::MechVentTypeBalanced, HPXML::MechVentTypeERV, HPXML::MechVentTypeHRV].include?(vent_mech.fan_type) }
820
+ vent_fan_kitchen = local_vent_fans.select { |vent_mech| vent_mech.fan_location == HPXML::LocationKitchen }
821
+ vent_fan_bath = local_vent_fans.select { |vent_mech| vent_mech.fan_location == HPXML::LocationBath }
822
+
823
+ if not (fan_cfis + fan_sup + fan_exh + fan_bal + vent_fan_kitchen + vent_fan_bath).empty?
824
+ mv_energy = UnitConversions.convert(results['End Use: Electricity: Mech Vent (MBtu)'], 'MBtu', 'GJ')
825
+
826
+ if not fan_cfis.empty?
827
+ if (fan_sup + fan_exh + fan_bal + vent_fan_kitchen + vent_fan_bath).empty?
828
+ # CFIS only, check for positive mech vent energy that is less than the energy if it had run 24/7
829
+ fan_gj = fan_cfis.map { |vent_mech| UnitConversions.convert(vent_mech.unit_fan_power * vent_mech.hours_in_operation * 365.0, 'Wh', 'GJ') }.sum(0.0)
830
+ assert_operator(mv_energy, :>, 0)
831
+ assert_operator(mv_energy, :<, fan_gj)
832
+ end
833
+ else
834
+ # Supply, exhaust, ERV, HRV, etc., check for appropriate mech vent energy
835
+ fan_gj = 0
836
+ if not fan_sup.empty?
837
+ fan_gj += fan_sup.map { |vent_mech| UnitConversions.convert(vent_mech.unit_fan_power * vent_mech.hours_in_operation * 365.0, 'Wh', 'GJ') }.sum(0.0)
838
+ end
839
+ if not fan_exh.empty?
840
+ fan_gj += fan_exh.map { |vent_mech| UnitConversions.convert(vent_mech.unit_fan_power * vent_mech.hours_in_operation * 365.0, 'Wh', 'GJ') }.sum(0.0)
841
+ end
842
+ if not fan_bal.empty?
843
+ fan_gj += fan_bal.map { |vent_mech| UnitConversions.convert(vent_mech.unit_fan_power * vent_mech.hours_in_operation * 365.0, 'Wh', 'GJ') }.sum(0.0)
844
+ end
845
+ if not vent_fan_kitchen.empty?
846
+ fan_gj += vent_fan_kitchen.map { |vent_kitchen| UnitConversions.convert(vent_kitchen.unit_fan_power * vent_kitchen.hours_in_operation * vent_kitchen.count * 365.0, 'Wh', 'GJ') }.sum(0.0)
847
+ end
848
+ if not vent_fan_bath.empty?
849
+ fan_gj += vent_fan_bath.map { |vent_bath| UnitConversions.convert(vent_bath.unit_fan_power * vent_bath.hours_in_operation * vent_bath.count * 365.0, 'Wh', 'GJ') }.sum(0.0)
850
+ end
851
+ # Maximum error that can be caused by rounding
852
+ assert_in_delta(mv_energy, fan_gj, 0.006)
853
+ end
854
+ end
855
+
856
+ tabular_map = { HPXML::ClothesWasher => Constants.ObjectNameClothesWasher,
857
+ HPXML::ClothesDryer => Constants.ObjectNameClothesDryer,
858
+ HPXML::Refrigerator => Constants.ObjectNameRefrigerator,
859
+ HPXML::Dishwasher => Constants.ObjectNameDishwasher,
860
+ HPXML::CookingRange => Constants.ObjectNameCookingRange }
861
+
862
+ (hpxml_bldg.clothes_washers + hpxml_bldg.clothes_dryers + hpxml_bldg.refrigerators + hpxml_bldg.dishwashers + hpxml_bldg.cooking_ranges).each do |appliance|
863
+ next unless hpxml_bldg.water_heating_systems.size > 0
864
+
865
+ # Location
866
+ hpxml_value = appliance.location
867
+ if hpxml_value.nil? || HPXML::conditioned_locations.include?(hpxml_value) || [HPXML::LocationOtherHeatedSpace, HPXML::LocationOtherMultifamilyBufferSpace, HPXML::LocationOtherNonFreezingSpace].include?(hpxml_value)
868
+ hpxml_value = HPXML::LocationConditionedSpace
869
+ end
870
+ tabular_value = tabular_map[appliance.class]
871
+ query = "SELECT Value FROM TabularDataWithStrings WHERE TableName='ElectricEquipment Internal Gains Nominal' AND ColumnName='Zone Name' AND RowName=(SELECT RowName FROM TabularDataWithStrings WHERE TableName='ElectricEquipment Internal Gains Nominal' AND ColumnName='Name' AND Value='#{tabular_value.upcase}')"
872
+ sql_value = sqlFile.execAndReturnFirstString(query).get
873
+ assert_equal(hpxml_value.upcase, sql_value)
874
+ end
875
+
876
+ # Lighting
877
+ ltg_energy = results.select { |k, _v| k.include? 'End Use: Electricity: Lighting' }.values.sum(0.0)
878
+ if not (hpxml_path.include?('vacancy-year-round') || hpxml_path.include?('residents-0'))
879
+ assert_equal(hpxml_bldg.lighting_groups.size > 0, ltg_energy > 0)
880
+ else
881
+ assert_operator(hpxml_bldg.lighting_groups.size, :>, 0)
882
+ assert_equal(0, ltg_energy)
883
+ end
884
+
885
+ # Get fuels
886
+ htg_fuels = []
887
+ htg_backup_fuels = []
888
+ wh_fuels = []
889
+ hpxml_bldg.heating_systems.each do |heating_system|
890
+ if heating_system.is_heat_pump_backup_system
891
+ htg_backup_fuels << heating_system.heating_system_fuel
892
+ else
893
+ htg_fuels << heating_system.heating_system_fuel
894
+ end
895
+ end
896
+ hpxml_bldg.cooling_systems.each do |cooling_system|
897
+ if cooling_system.has_integrated_heating
898
+ htg_fuels << cooling_system.integrated_heating_system_fuel
899
+ end
900
+ end
901
+ hpxml_bldg.heat_pumps.each do |heat_pump|
902
+ if heat_pump.fraction_heat_load_served > 0
903
+ htg_backup_fuels << heat_pump.backup_heating_fuel
904
+ end
905
+ end
906
+ hpxml_bldg.water_heating_systems.each do |water_heating_system|
907
+ related_hvac = water_heating_system.related_hvac_system
908
+ if related_hvac.nil?
909
+ wh_fuels << water_heating_system.fuel_type
910
+ elsif related_hvac.respond_to? :heating_system_fuel
911
+ wh_fuels << related_hvac.heating_system_fuel
912
+ end
913
+ end
914
+
915
+ is_warm_climate = false
916
+ if ['USA_FL_Miami.Intl.AP.722020_TMY3.epw',
917
+ 'USA_HI_Honolulu.Intl.AP.911820_TMY3.epw',
918
+ 'USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3.epw'].include? hpxml_bldg.climate_and_risk_zones.weather_station_epw_filepath
919
+ is_warm_climate = true
920
+ end
921
+
922
+ # Fuel consumption checks
923
+ [HPXML::FuelTypeNaturalGas,
924
+ HPXML::FuelTypeOil,
925
+ HPXML::FuelTypeKerosene,
926
+ HPXML::FuelTypePropane,
927
+ HPXML::FuelTypeWoodCord,
928
+ HPXML::FuelTypeWoodPellets,
929
+ HPXML::FuelTypeCoal].each do |fuel|
930
+ fuel_name = fuel.split.map(&:capitalize).join(' ')
931
+ fuel_name += ' Cord' if fuel_name == 'Wood'
932
+ energy_htg = results.fetch("End Use: #{fuel_name}: Heating (MBtu)", 0)
933
+ energy_hp_backup = results.fetch("End Use: #{fuel_name}: Heating Heat Pump Backup (MBtu)", 0)
934
+ energy_dhw = results.fetch("End Use: #{fuel_name}: Hot Water (MBtu)", 0)
935
+ energy_cd = results.fetch("End Use: #{fuel_name}: Clothes Dryer (MBtu)", 0)
936
+ energy_cr = results.fetch("End Use: #{fuel_name}: Range/Oven (MBtu)", 0)
937
+ if htg_fuels.include? fuel
938
+ if (not hpxml_path.include? 'autosize') && (not is_warm_climate)
939
+ assert_operator(energy_htg, :>, 0)
940
+ end
941
+ else
942
+ assert_equal(0, energy_htg)
943
+ end
944
+ if htg_backup_fuels.include? fuel
945
+ if (not hpxml_path.include? 'autosize') && (not is_warm_climate)
946
+ assert_operator(energy_hp_backup, :>, 0)
947
+ end
948
+ else
949
+ assert_equal(0, energy_hp_backup)
950
+ end
951
+ if wh_fuels.include? fuel
952
+ assert_operator(energy_dhw, :>, 0)
953
+ else
954
+ assert_equal(0, energy_dhw)
955
+ end
956
+ if (hpxml_bldg.clothes_dryers.size > 0) && (hpxml_bldg.clothes_dryers[0].fuel_type == fuel)
957
+ assert_operator(energy_cd, :>, 0)
958
+ else
959
+ assert_equal(0, energy_cd)
960
+ end
961
+ if (hpxml_bldg.cooking_ranges.size > 0) && (hpxml_bldg.cooking_ranges[0].fuel_type == fuel)
962
+ assert_operator(energy_cr, :>, 0)
963
+ else
964
+ assert_equal(0, energy_cr)
965
+ end
966
+ end
967
+
968
+ # Check unmet hours
969
+ unmet_hours_htg = results.select { |k, _v| k.include? 'Unmet Hours: Heating' }.values.sum(0.0)
970
+ unmet_hours_clg = results.select { |k, _v| k.include? 'Unmet Hours: Cooling' }.values.sum(0.0)
971
+ if hpxml_path.include? 'base-hvac-undersized.xml'
972
+ assert_operator(unmet_hours_htg, :>, 1000)
973
+ assert_operator(unmet_hours_clg, :>, 1000)
974
+ else
975
+ if hpxml_bldg.total_fraction_heat_load_served == 0
976
+ assert_equal(0, unmet_hours_htg)
977
+ else
978
+ assert_operator(unmet_hours_htg, :<, 400)
979
+ end
980
+ if hpxml_bldg.total_fraction_cool_load_served == 0
981
+ assert_equal(0, unmet_hours_clg)
982
+ else
983
+ assert_operator(unmet_hours_clg, :<, 400)
984
+ end
985
+ end
986
+
987
+ sqlFile.close
988
+
989
+ # Ensure sql file is immediately freed; otherwise we can get
990
+ # errors on Windows when trying to delete this file.
991
+ GC.start()
992
+ end
993
+
994
+ def _check_unit_multiplier_results(hpxml_bldg, annual_results_1x, annual_results_10x, timeseries_results_1x, timeseries_results_10x, unit_multiplier)
995
+ # Check that results_10x are expected compared to results_1x
996
+
997
+ def get_tolerances(key)
998
+ if key.include?('(MBtu)') || key.include?('(kBtu)') || key.include?('(kWh)')
999
+ # Check that the energy difference is less than 0.5 MBtu or less than 5%
1000
+ abs_delta_tol = 0.5 # MBtu
1001
+ abs_frac_tol = 0.05
1002
+ if key.include?('(kBtu)')
1003
+ abs_delta_tol = UnitConversions.convert(abs_delta_tol, 'MBtu', 'kBtu')
1004
+ elsif key.include?('(kWh)')
1005
+ abs_delta_tol = UnitConversions.convert(abs_delta_tol, 'MBtu', 'kWh')
1006
+ end
1007
+ elsif key.include?('Peak Electricity:')
1008
+ # Check that the peak electricity difference is less than 500 W or less than 2%
1009
+ # Wider tolerances than others because a small change in when an event (like the
1010
+ # water heating firing) occurs can significantly impact the peak.
1011
+ abs_delta_tol = 500.0
1012
+ abs_frac_tol = 0.02
1013
+ elsif key.include?('Peak Load:')
1014
+ # Check that the peak load difference is less than 0.2 kBtu/hr or less than 5%
1015
+ abs_delta_tol = 0.2
1016
+ abs_frac_tol = 0.05
1017
+ elsif key.include?('Hot Water:')
1018
+ # Check that the hot water usage difference is less than 10 gal/yr or less than 2%
1019
+ abs_delta_tol = 10.0
1020
+ abs_frac_tol = 0.02
1021
+ elsif key.include?('Resilience: Battery')
1022
+ # Check that the battery resilience difference is less than 1 hr or less than 1%
1023
+ abs_delta_tol = 1.0
1024
+ abs_frac_tol = 0.01
1025
+ elsif key.include?('Airflow:')
1026
+ # Check that airflow rate difference is less than 0.1 cfm or less than 0.5%
1027
+ abs_delta_tol = 0.1
1028
+ abs_frac_tol = 0.005
1029
+ elsif key.include?('Unmet Hours:')
1030
+ # Check that the unmet hours difference is less than 10 hrs
1031
+ abs_delta_tol = 10
1032
+ abs_frac_tol = nil
1033
+ elsif key.include?('HVAC Capacity:') || key.include?('HVAC Design Load:') || key.include?('HVAC Design Temperature:') || key.include?('Weather:')
1034
+ # Check that there is no difference
1035
+ abs_delta_tol = 0
1036
+ abs_frac_tol = nil
1037
+ else
1038
+ fail "Unexpected results key: #{key}."
1039
+ end
1040
+
1041
+ return abs_delta_tol, abs_frac_tol
1042
+ end
1043
+
1044
+ # Number of systems and thermal zones change between the 1x and 10x runs,
1045
+ # so remove these from the comparison
1046
+ ['System Use:', 'Temperature:'].each do |key|
1047
+ annual_results_1x.delete_if { |k, _v| k.start_with? key }
1048
+ annual_results_10x.delete_if { |k, _v| k.start_with? key }
1049
+ timeseries_results_1x.delete_if { |k, _v| k.start_with? key }
1050
+ timeseries_results_10x.delete_if { |k, _v| k.start_with? key }
1051
+ end
1052
+
1053
+ # Compare annual and timeseries results
1054
+ assert_equal(annual_results_1x.keys.sort, annual_results_10x.keys.sort)
1055
+ assert_equal(timeseries_results_1x.keys.sort, timeseries_results_10x.keys.sort)
1056
+
1057
+ { annual_results_1x => annual_results_10x,
1058
+ timeseries_results_1x => timeseries_results_10x }.each do |results_1x, results_10x|
1059
+ results_1x.each do |key, vals_1x|
1060
+ abs_delta_tol, abs_frac_tol = get_tolerances(key)
1061
+
1062
+ vals_10x = results_10x[key]
1063
+ if not vals_1x.is_a? Array
1064
+ vals_1x = [vals_1x]
1065
+ vals_10x = [vals_10x]
1066
+ end
1067
+
1068
+ vals_1x.zip(vals_10x).each do |val_1x, val_10x|
1069
+ if not (key.include?('Unmet Hours') ||
1070
+ key.include?('HVAC Design Temperature') ||
1071
+ key.include?('Weather'))
1072
+ # These outputs shouldn't change based on the unit multiplier
1073
+ val_1x *= unit_multiplier
1074
+ end
1075
+
1076
+ abs_val_delta = (val_1x - val_10x).abs
1077
+ avg_val = [val_1x, val_10x].sum / 2.0
1078
+ if avg_val > 0
1079
+ abs_val_frac = abs_val_delta / avg_val
1080
+ end
1081
+
1082
+ # FUTURE: Address these
1083
+ if hpxml_bldg.water_heating_systems.select { |wh| wh.water_heater_type == HPXML::WaterHeaterTypeHeatPump }.size > 0
1084
+ next if key.include?('Airflow:')
1085
+ next if key.include?('Peak')
1086
+ end
1087
+ if hpxml_bldg.water_heating_systems.select { |wh| [HPXML::WaterHeaterTypeCombiStorage, HPXML::WaterHeaterTypeCombiTankless].include? wh.water_heater_type }.size > 0
1088
+ next if key.include?('Hot Water')
1089
+ end
1090
+
1091
+ # Uncomment these lines to debug:
1092
+ # if val_1x != 0 or val_10x != 0
1093
+ # puts "[#{key}] 1x=#{val_1x} 10x=#{val_10x}"
1094
+ # end
1095
+ if abs_frac_tol.nil?
1096
+ if abs_delta_tol == 0
1097
+ assert_equal(val_1x, val_10x)
1098
+ else
1099
+ assert_in_delta(val_1x, val_10x, abs_delta_tol)
1100
+ end
1101
+ else
1102
+ assert((abs_val_delta <= abs_delta_tol) || (!abs_val_frac.nil? && abs_val_frac <= abs_frac_tol))
1103
+ end
1104
+ end
1105
+ end
1106
+ end
1107
+ end
1108
+
1109
+ def _write_results(results, csv_out)
1110
+ require 'csv'
1111
+
1112
+ output_keys = []
1113
+ results.values.each do |xml_results|
1114
+ # Don't include emissions and system uses in output file/CI results
1115
+ xml_results.delete_if { |k, _v| k.start_with? 'Emissions:' }
1116
+ xml_results.delete_if { |k, _v| k.start_with? 'System Use:' }
1117
+
1118
+ xml_results.keys.each do |key|
1119
+ next if output_keys.include? key
1120
+
1121
+ output_keys << key
1122
+ end
1123
+ end
1124
+
1125
+ CSV.open(csv_out, 'w') do |csv|
1126
+ csv << ['HPXML'] + output_keys
1127
+ results.sort.each do |xml, xml_results|
1128
+ csv_row = [xml]
1129
+ output_keys.each do |key|
1130
+ if xml_results[key].nil?
1131
+ csv_row << 0
1132
+ else
1133
+ csv_row << xml_results[key]
1134
+ end
1135
+ end
1136
+ csv << csv_row
1137
+ end
1138
+ end
1139
+
1140
+ puts "Wrote results to #{csv_out}."
1141
+ end