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
@@ -1,3 +1,8 @@
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
+
1
6
  # frozen_string_literal: true
2
7
 
3
8
  # see the URL below for information on how to write OpenStudio measures
@@ -127,6 +132,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
127
132
  arg.setDefaultValue(true)
128
133
  args << arg
129
134
 
135
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_resilience', false)
136
+ arg.setDisplayName('Generate Annual Output: Resilience')
137
+ arg.setDescription('Generates annual resilience outputs.')
138
+ arg.setDefaultValue(true)
139
+ args << arg
140
+
130
141
  timeseries_frequency_chs = OpenStudio::StringVector.new
131
142
  timeseries_frequency_chs << 'none'
132
143
  timeseries_frequency_chs << 'timestep'
@@ -223,6 +234,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
223
234
  arg.setDefaultValue(false)
224
235
  args << arg
225
236
 
237
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_resilience', false)
238
+ arg.setDisplayName('Generate Timeseries Output: Resilience')
239
+ arg.setDescription('Generates timeseries resilience outputs.')
240
+ arg.setDefaultValue(false)
241
+ args << arg
242
+
226
243
  timestamp_chs = OpenStudio::StringVector.new
227
244
  timestamp_chs << 'start'
228
245
  timestamp_chs << 'end'
@@ -267,6 +284,31 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
267
284
  return args
268
285
  end
269
286
 
287
+ # define the outputs that the measure will create
288
+ def outputs
289
+ result = OpenStudio::Measure::OSOutputVector.new
290
+
291
+ setup_outputs(true)
292
+
293
+ [@totals,
294
+ @fuels,
295
+ @end_uses,
296
+ @loads,
297
+ @unmet_hours,
298
+ @peak_fuels,
299
+ @peak_loads,
300
+ @component_loads,
301
+ @hot_water_uses,
302
+ @resilience].each do |outputs|
303
+ outputs.values.each do |obj|
304
+ output_name = OpenStudio::toUnderscoreCase("#{obj.name} #{obj.annual_units}")
305
+ result << OpenStudio::Measure::OSOutput.makeDoubleOutput(output_name.chomp('_'))
306
+ end
307
+ end
308
+
309
+ return result
310
+ end
311
+
270
312
  def get_arguments(runner, arguments, user_arguments)
271
313
  args = get_argument_values(runner, arguments, user_arguments)
272
314
  args.each do |k, val|
@@ -310,16 +352,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
310
352
  return result
311
353
  end
312
354
 
313
- unmet_hours_program = @model.getModelObjectByName(Constants.ObjectNameUnmetHoursProgram.gsub(' ', '_')).get.to_EnergyManagementSystemProgram.get
314
- total_loads_program = @model.getModelObjectByName(Constants.ObjectNameTotalLoadsProgram.gsub(' ', '_')).get.to_EnergyManagementSystemProgram.get
315
- comp_loads_program = @model.getModelObjectByName(Constants.ObjectNameComponentLoadsProgram.gsub(' ', '_'))
316
- if comp_loads_program.is_initialized
317
- comp_loads_program = comp_loads_program.get.to_EnergyManagementSystemProgram.get
318
- else
319
- comp_loads_program = nil
320
- end
321
- has_heating = @model.getBuilding.additionalProperties.getFeatureAsBoolean('has_heating').get
322
- has_cooling = @model.getBuilding.additionalProperties.getFeatureAsBoolean('has_cooling').get
355
+ unmet_hours_program = @model.getEnergyManagementSystemPrograms.find { |p| p.additionalProperties.getFeatureAsString('ObjectType').to_s == Constants.ObjectNameUnmetHoursProgram }
356
+ total_loads_program = @model.getEnergyManagementSystemPrograms.find { |p| p.additionalProperties.getFeatureAsString('ObjectType').to_s == Constants.ObjectNameTotalLoadsProgram }
357
+ comp_loads_program = @model.getEnergyManagementSystemPrograms.find { |p| p.additionalProperties.getFeatureAsString('ObjectType').to_s == Constants.ObjectNameComponentLoadsProgram }
358
+ heated_zones = eval(@model.getBuilding.additionalProperties.getFeatureAsString('heated_zones').get)
359
+ cooled_zones = eval(@model.getBuilding.additionalProperties.getFeatureAsString('cooled_zones').get)
323
360
 
324
361
  args = get_arguments(runner, arguments(model), user_arguments)
325
362
 
@@ -353,6 +390,22 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
353
390
  if args[:include_timeseries_fuel_consumptions]
354
391
  result << OpenStudio::IdfObject.load("Output:Meter,ElectricStorage:ElectricityProduced,#{args[:timeseries_frequency]};").get
355
392
  end
393
+
394
+ # Resilience
395
+ if args[:include_annual_resilience] || args[:include_timeseries_resilience]
396
+ resilience_frequency = 'timestep'
397
+ if args[:timeseries_frequency] != 'timestep'
398
+ resilience_frequency = 'hourly'
399
+ end
400
+ result << OpenStudio::IdfObject.load("Output:Meter,Electricity:Facility,#{resilience_frequency};").get
401
+ result << OpenStudio::IdfObject.load("Output:Meter,ElectricityProduced:Facility,#{resilience_frequency};").get
402
+ result << OpenStudio::IdfObject.load("Output:Meter,ElectricStorage:ElectricityProduced,#{resilience_frequency};").get
403
+ @resilience.values.each do |resilience|
404
+ resilience.variables.each do |_sys_id, varkey, var|
405
+ result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},#{resilience_frequency};").get
406
+ end
407
+ end
408
+ end
356
409
  end
357
410
 
358
411
  # End Use/Hot Water Use/Ideal Load outputs
@@ -371,6 +424,18 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
371
424
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},hourly;").get
372
425
  end
373
426
  end
427
+ use.meters.each do |_sys_id, _varkey, var|
428
+ result << OpenStudio::IdfObject.load("Output:Meter,#{var},runperiod;").get
429
+ if include_ts
430
+ result << OpenStudio::IdfObject.load("Output:Meter,#{var},#{args[:timeseries_frequency]};").get
431
+ end
432
+ next unless use.is_a?(EndUse)
433
+
434
+ fuel_type, _end_use = key
435
+ if fuel_type == FT::Elec && args[:include_hourly_electric_end_use_consumptions]
436
+ result << OpenStudio::IdfObject.load("Output:Meter,#{var},hourly;").get
437
+ end
438
+ end
374
439
  end
375
440
  end
376
441
 
@@ -436,26 +501,27 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
436
501
  HPXML::LocationExteriorWall,
437
502
  HPXML::LocationUnderSlab]
438
503
  keys.each do |key|
439
- next if @model.getScheduleConstants.select { |o| o.name.to_s == key }.size == 0
504
+ schedules = @model.getScheduleConstants.select { |sch| sch.additionalProperties.getFeatureAsString('ObjectType').to_s == key }
505
+ next if schedules.empty?
440
506
 
441
- result << OpenStudio::IdfObject.load("Output:Variable,#{key},Schedule Value,#{args[:timeseries_frequency]};").get
507
+ result << OpenStudio::IdfObject.load("Output:Variable,#{schedules[0].name.to_s.upcase},Schedule Value,#{args[:timeseries_frequency]};").get
442
508
  end
443
509
  # Also report thermostat setpoints
444
- if has_heating
445
- result << OpenStudio::IdfObject.load("Output:Variable,#{HPXML::LocationLivingSpace.upcase},Zone Thermostat Heating Setpoint Temperature,#{args[:timeseries_frequency]};").get
510
+ heated_zones.each do |heated_zone|
511
+ result << OpenStudio::IdfObject.load("Output:Variable,#{heated_zone.upcase},Zone Thermostat Heating Setpoint Temperature,#{args[:timeseries_frequency]};").get
446
512
  end
447
- if has_cooling
448
- result << OpenStudio::IdfObject.load("Output:Variable,#{HPXML::LocationLivingSpace.upcase},Zone Thermostat Cooling Setpoint Temperature,#{args[:timeseries_frequency]};").get
513
+ cooled_zones.each do |cooled_zone|
514
+ result << OpenStudio::IdfObject.load("Output:Variable,#{cooled_zone.upcase},Zone Thermostat Cooling Setpoint Temperature,#{args[:timeseries_frequency]};").get
449
515
  end
450
516
  end
451
517
 
452
518
  # Airflow outputs (timeseries only)
453
519
  if args[:include_timeseries_airflows]
454
- @airflows.values.each do |airflow|
455
- ems_program = @model.getModelObjectByName(airflow.ems_program.gsub(' ', '_')).get.to_EnergyManagementSystemProgram.get
456
- airflow.ems_variables.each do |ems_variable|
457
- result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{ems_variable}_timeseries_outvar,#{ems_variable},Averaged,ZoneTimestep,#{ems_program.name},m^3/s;").get
458
- result << OpenStudio::IdfObject.load("Output:Variable,*,#{ems_variable}_timeseries_outvar,#{args[:timeseries_frequency]};").get
520
+ @airflows.each do |_airflow_type, airflow|
521
+ ems_programs = @model.getEnergyManagementSystemPrograms.select { |p| p.additionalProperties.getFeatureAsString('ObjectType').to_s == airflow.ems_program }
522
+ ems_programs.each_with_index do |_ems_program, i|
523
+ unit_prefix = ems_programs.size > 1 ? "unit#{i + 1}_" : ''
524
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{unit_prefix}#{airflow.ems_variable}_timeseries_outvar,#{args[:timeseries_frequency]};").get
459
525
  end
460
526
  end
461
527
  end
@@ -500,11 +566,13 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
500
566
  args[:use_dview_format] = false
501
567
  end
502
568
 
503
- output_dir = File.dirname(runner.lastEpwFilePath.get.to_s)
504
-
505
569
  hpxml_defaults_path = @model.getBuilding.additionalProperties.getFeatureAsString('hpxml_defaults_path').get
570
+ output_dir = File.dirname(hpxml_defaults_path)
506
571
  building_id = @model.getBuilding.additionalProperties.getFeatureAsString('building_id').get
507
- @hpxml = HPXML.new(hpxml_path: hpxml_defaults_path, building_id: building_id)
572
+ hpxml = HPXML.new(hpxml_path: hpxml_defaults_path, building_id: building_id)
573
+
574
+ @hpxml_header = hpxml.header
575
+ @hpxml_bldgs = hpxml.buildings
508
576
 
509
577
  setup_outputs(false, args[:user_output_variables])
510
578
 
@@ -518,8 +586,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
518
586
  if File.exist? msgpack_timeseries_path
519
587
  @msgpackDataTimeseries = MessagePack.unpack(File.read(msgpack_timeseries_path, mode: 'rb'))
520
588
  end
521
- if not @emissions.empty?
522
- @msgpackDataHourly = MessagePack.unpack(File.read(File.join(output_dir, 'eplusout_hourly.msgpack'), mode: 'rb'))
589
+ if args[:timeseries_frequency] != 'hourly'
590
+ msgpack_hourly_path = File.join(output_dir, 'eplusout_hourly.msgpack')
591
+ if File.exist? msgpack_hourly_path
592
+ @msgpackDataHourly = MessagePack.unpack(File.read(msgpack_hourly_path, mode: 'rb'))
593
+ end
523
594
  end
524
595
 
525
596
  # Set paths
@@ -535,11 +606,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
535
606
  end
536
607
 
537
608
  if args[:timeseries_frequency] != 'none'
538
- @timestamps, timestamps_dst, timestamps_utc = get_timestamps(@msgpackDataTimeseries, @hpxml, args)
609
+ @timestamps, timestamps_dst, timestamps_utc = get_timestamps(@msgpackDataTimeseries, @hpxml_header, @hpxml_bldgs, args)
539
610
  end
540
611
 
541
612
  # Retrieve outputs
542
- outputs = get_outputs(runner, args)
613
+ outputs = get_outputs(runner, args, building_id)
543
614
 
544
615
  if not check_for_errors(runner, outputs)
545
616
  return false
@@ -552,24 +623,24 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
552
623
  return true
553
624
  end
554
625
 
555
- def get_timestamps(msgpackData, hpxml, args)
626
+ def get_timestamps(msgpackData, hpxml_header, hpxml_bldgs, args)
556
627
  return if msgpackData.nil?
557
628
 
558
629
  ep_timestamps = msgpackData['Rows'].map { |r| r.keys[0] }
559
630
 
560
631
  if args[:add_timeseries_dst_column] || args[:use_dview_format]
561
- dst_start_ts = Time.utc(hpxml.header.sim_calendar_year, hpxml.header.dst_begin_month, hpxml.header.dst_begin_day, 2)
562
- dst_end_ts = Time.utc(hpxml.header.sim_calendar_year, hpxml.header.dst_end_month, hpxml.header.dst_end_day, 1)
632
+ dst_start_ts = Time.utc(hpxml_header.sim_calendar_year, hpxml_bldgs[0].dst_begin_month, hpxml_bldgs[0].dst_begin_day, 2)
633
+ dst_end_ts = Time.utc(hpxml_header.sim_calendar_year, hpxml_bldgs[0].dst_end_month, hpxml_bldgs[0].dst_end_day, 1)
563
634
  end
564
635
  if args[:add_timeseries_utc_column]
565
- utc_offset = hpxml.header.time_zone_utc_offset
636
+ utc_offset = hpxml_bldgs[0].time_zone_utc_offset
566
637
  utc_offset *= 3600 # seconds
567
638
  end
568
639
 
569
640
  timestamps = []
570
641
  timestamps_dst = [] if args[:add_timeseries_dst_column] || args[:use_dview_format]
571
642
  timestamps_utc = [] if args[:add_timeseries_utc_column]
572
- year = hpxml.header.sim_calendar_year
643
+ year = hpxml_header.sim_calendar_year
573
644
  ep_timestamps.each do |ep_timestamp|
574
645
  month_day, hour_minute = ep_timestamp.split(' ')
575
646
  month, day = month_day.split('/').map(&:to_i)
@@ -578,7 +649,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
578
649
  # Convert from EnergyPlus default (end-of-timestep) to start-of-timestep convention
579
650
  if args[:timeseries_timestamp_convention] == 'start'
580
651
  if args[:timeseries_frequency] == 'timestep'
581
- ts_offset = hpxml.header.timestep * 60 # seconds
652
+ ts_offset = hpxml_header.timestep * 60 # seconds
582
653
  elsif args[:timeseries_frequency] == 'hourly'
583
654
  ts_offset = 60 * 60 # seconds
584
655
  elsif args[:timeseries_frequency] == 'daily'
@@ -613,7 +684,37 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
613
684
  return timestamps, timestamps_dst, timestamps_utc
614
685
  end
615
686
 
616
- def get_outputs(runner, args)
687
+ def get_n_hours_per_period(timeseries_frequency, sim_start_day_of_year, sim_end_day_of_year, year)
688
+ if timeseries_frequency == 'daily'
689
+ n_hours_per_period = [24] * (sim_end_day_of_year - sim_start_day_of_year + 1)
690
+ elsif timeseries_frequency == 'monthly'
691
+ n_days_per_month = Constants.NumDaysInMonths(year)
692
+ n_days_per_period = n_days_per_month[@hpxml_header.sim_begin_month - 1..@hpxml_header.sim_end_month - 1]
693
+ n_days_per_period[0] -= @hpxml_header.sim_begin_day - 1
694
+ n_days_per_period[-1] = @hpxml_header.sim_end_day
695
+ n_hours_per_period = n_days_per_period.map { |x| x * 24 }
696
+ end
697
+ return n_hours_per_period
698
+ end
699
+
700
+ def rollup_timeseries_output_to_daily_or_monthly(timeseries_output, timeseries_frequency, average = false)
701
+ year = @hpxml_header.sim_calendar_year
702
+ sim_start_day_of_year, sim_end_day_of_year, _sim_start_hour, _sim_end_hour = get_sim_times_of_year(year)
703
+ n_hours_per_period = get_n_hours_per_period(timeseries_frequency, sim_start_day_of_year, sim_end_day_of_year, year)
704
+ fail 'Unexpected failure for n_hours_per_period calculations.' if n_hours_per_period.sum != timeseries_output.size
705
+
706
+ ts_output = []
707
+ start_hour = 0
708
+ n_hours_per_period.each do |n_hours|
709
+ timeseries = timeseries_output[start_hour..start_hour + n_hours - 1].sum()
710
+ timeseries /= timeseries_output[start_hour..start_hour + n_hours - 1].size if average
711
+ ts_output << timeseries
712
+ start_hour += n_hours
713
+ end
714
+ return ts_output
715
+ end
716
+
717
+ def get_outputs(runner, args, building_id)
617
718
  outputs = {}
618
719
 
619
720
  args = setup_timeseries_includes(@emissions, args)
@@ -643,6 +744,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
643
744
  months = ['June', 'July', 'August']
644
745
  elsif (season == PFT::Winter && is_northern_hemisphere) || (season == PFT::Summer && is_southern_hemisphere)
645
746
  months = ['December', 'January', 'February']
747
+ elsif season == PFT::Annual
748
+ months = ['Maximum of Months']
646
749
  end
647
750
  for month in months
648
751
  val = get_tabular_data_value(peak_fuel.report.upcase, 'Meter', 'Custom Monthly Report', [month], 'ELECTRICITY:FACILITY {Maximum}', peak_fuel.annual_units)
@@ -710,6 +813,29 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
710
813
  end_use.hourly_output_by_system[sys_id] = get_report_variable_data_timeseries(keys, vars, UnitConversions.convert(1.0, 'J', end_use.timeseries_units), 0, 'hourly', is_negative: (end_use.is_negative || end_use.is_storage))
711
814
  end
712
815
  end
816
+ end_use.meters.map { |v| v[0] }.uniq.each do |sys_id|
817
+ vars = end_use.meters.select { |v| v[0] == sys_id }.map { |v| v[2] }
818
+
819
+ end_use.annual_output_by_system[sys_id] = 0.0 if end_use.annual_output_by_system[sys_id].nil?
820
+ end_use.annual_output_by_system[sys_id] += get_report_meter_data_annual(vars, UnitConversions.convert(1.0, 'J', end_use.annual_units))
821
+
822
+ if args[:include_timeseries_end_use_consumptions]
823
+ values = get_report_meter_data_timeseries(vars, UnitConversions.convert(1.0, 'J', end_use.timeseries_units), 0, args[:timeseries_frequency])
824
+ if end_use.timeseries_output_by_system[sys_id].nil?
825
+ end_use.timeseries_output_by_system[sys_id] = values
826
+ else
827
+ end_use.timeseries_output_by_system[sys_id] = end_use.timeseries_output_by_system[sys_id].zip(values).map { |x, y| x + y }
828
+ end
829
+ end
830
+ next unless args[:include_hourly_electric_end_use_consumptions] && fuel_type == FT::Elec
831
+
832
+ values = get_report_meter_data_timeseries(vars, UnitConversions.convert(1.0, 'J', end_use.timeseries_units), 0, 'hourly')
833
+ if end_use.hourly_output_by_system[sys_id].nil?
834
+ end_use.hourly_output_by_system[sys_id] = values
835
+ else
836
+ end_use.hourly_output_by_system[sys_id] = end_use.hourly_output_by_system[sys_id].zip(values).map { |x, y| x + y }
837
+ end
838
+ end
713
839
  end
714
840
 
715
841
  # Disaggregate 8760 GSHP shared pump energy into heating vs cooling by
@@ -746,57 +872,58 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
746
872
  end
747
873
  end
748
874
 
749
- # Apply Heating/Cooling DSEs
750
- (@hpxml.heating_systems + @hpxml.heat_pumps).each do |htg_system|
751
- next unless (htg_system.is_a?(HPXML::HeatingSystem) && htg_system.is_heat_pump_backup_system) || htg_system.fraction_heat_load_served > 0
752
- next if htg_system.distribution_system_idref.nil?
753
- next unless htg_system.distribution_system.distribution_system_type == HPXML::HVACDistributionTypeDSE
754
- next if htg_system.distribution_system.annual_heating_dse.nil?
875
+ @hpxml_bldgs.each do |hpxml_bldg|
876
+ # Apply Heating/Cooling DSEs
877
+ (hpxml_bldg.heating_systems + hpxml_bldg.heat_pumps).each do |htg_system|
878
+ next unless (htg_system.is_a?(HPXML::HeatingSystem) && htg_system.is_heat_pump_backup_system) || htg_system.fraction_heat_load_served > 0
879
+ next if htg_system.distribution_system_idref.nil?
880
+ next unless htg_system.distribution_system.distribution_system_type == HPXML::HVACDistributionTypeDSE
881
+ next if htg_system.distribution_system.annual_heating_dse.nil?
755
882
 
756
- dse = htg_system.distribution_system.annual_heating_dse
757
- @fuels.each do |fuel_type, fuel|
758
- [EUT::Heating, EUT::HeatingHeatPumpBackup, EUT::HeatingFanPump, EUT::HeatingHeatPumpBackupFanPump].each do |end_use_type|
759
- end_use = @end_uses[[fuel_type, end_use_type]]
760
- next if end_use.nil?
883
+ dse = htg_system.distribution_system.annual_heating_dse
884
+ @fuels.each do |fuel_type, fuel|
885
+ [EUT::Heating, EUT::HeatingHeatPumpBackup, EUT::HeatingFanPump, EUT::HeatingHeatPumpBackupFanPump].each do |end_use_type|
886
+ end_use = @end_uses[[fuel_type, end_use_type]]
887
+ next if end_use.nil?
888
+ next if end_use.annual_output_by_system[htg_system.id].nil?
761
889
 
762
- if not end_use.annual_output_by_system[htg_system.id].nil?
763
890
  apply_multiplier_to_output(end_use, fuel, htg_system.id, 1.0 / dse)
764
891
  end
765
892
  end
766
893
  end
767
- end
768
- (@hpxml.cooling_systems + @hpxml.heat_pumps).each do |clg_system|
769
- next unless clg_system.fraction_cool_load_served > 0
770
- next if clg_system.distribution_system_idref.nil?
771
- next unless clg_system.distribution_system.distribution_system_type == HPXML::HVACDistributionTypeDSE
772
- next if clg_system.distribution_system.annual_cooling_dse.nil?
894
+ (hpxml_bldg.cooling_systems + hpxml_bldg.heat_pumps).each do |clg_system|
895
+ next unless clg_system.fraction_cool_load_served > 0
896
+ next if clg_system.distribution_system_idref.nil?
897
+ next unless clg_system.distribution_system.distribution_system_type == HPXML::HVACDistributionTypeDSE
898
+ next if clg_system.distribution_system.annual_cooling_dse.nil?
773
899
 
774
- dse = clg_system.distribution_system.annual_cooling_dse
775
- @fuels.each do |fuel_type, fuel|
776
- [EUT::Cooling, EUT::CoolingFanPump].each do |end_use_type|
777
- end_use = @end_uses[[fuel_type, end_use_type]]
778
- next if end_use.nil?
779
- next if end_use.annual_output_by_system[clg_system.id].nil?
900
+ dse = clg_system.distribution_system.annual_cooling_dse
901
+ @fuels.each do |fuel_type, fuel|
902
+ [EUT::Cooling, EUT::CoolingFanPump].each do |end_use_type|
903
+ end_use = @end_uses[[fuel_type, end_use_type]]
904
+ next if end_use.nil?
905
+ next if end_use.annual_output_by_system[clg_system.id].nil?
780
906
 
781
- apply_multiplier_to_output(end_use, fuel, clg_system.id, 1.0 / dse)
907
+ apply_multiplier_to_output(end_use, fuel, clg_system.id, 1.0 / dse)
908
+ end
782
909
  end
783
910
  end
784
- end
785
911
 
786
- # Apply solar fraction to load for simple solar water heating systems
787
- @hpxml.solar_thermal_systems.each do |solar_system|
788
- next if solar_system.solar_fraction.nil?
912
+ # Apply solar fraction to load for simple solar water heating systems
913
+ hpxml_bldg.solar_thermal_systems.each do |solar_system|
914
+ next if solar_system.solar_fraction.nil?
789
915
 
790
- @loads[LT::HotWaterSolarThermal].annual_output = 0.0 if @loads[LT::HotWaterSolarThermal].annual_output.nil?
791
- @loads[LT::HotWaterSolarThermal].timeseries_output = [0.0] * @timestamps.size if @loads[LT::HotWaterSolarThermal].timeseries_output.nil?
916
+ @loads[LT::HotWaterSolarThermal].annual_output = 0.0 if @loads[LT::HotWaterSolarThermal].annual_output.nil?
917
+ @loads[LT::HotWaterSolarThermal].timeseries_output = [0.0] * @timestamps.size if @loads[LT::HotWaterSolarThermal].timeseries_output.nil?
792
918
 
793
- if not solar_system.water_heating_system.nil?
794
- dhw_ids = [solar_system.water_heating_system.id]
795
- else # Apply to all water heating systems
796
- dhw_ids = @hpxml.water_heating_systems.map { |dhw| dhw.id }
797
- end
798
- dhw_ids.each do |dhw_id|
799
- apply_multiplier_to_output(@loads[LT::HotWaterDelivered], @loads[LT::HotWaterSolarThermal], dhw_id, 1.0 / (1.0 - solar_system.solar_fraction))
919
+ if not solar_system.water_heating_system.nil?
920
+ dhw_ids = [solar_system.water_heating_system.id]
921
+ else # Apply to all water heating systems
922
+ dhw_ids = hpxml_bldg.water_heating_systems.map { |dhw| dhw.id }
923
+ end
924
+ dhw_ids.each do |dhw_id|
925
+ apply_multiplier_to_output(@loads[LT::HotWaterDelivered], @loads[LT::HotWaterSolarThermal], dhw_id, 1.0 / (1.0 - solar_system.solar_fraction))
926
+ end
800
927
  end
801
928
  end
802
929
 
@@ -872,46 +999,158 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
872
999
  @totals[TE::Net].timeseries_output = @totals[TE::Total].timeseries_output.zip(outputs[:elec_prod_timeseries]).map { |x, y| x + y * unit_conv }
873
1000
  end
874
1001
 
1002
+ # Resilience
1003
+ @resilience.each do |key, resilience|
1004
+ next unless key == RT::Battery
1005
+ next unless (args[:include_annual_resilience] || args[:include_timeseries_resilience])
1006
+ next if resilience.variables.empty?
1007
+
1008
+ batteries = []
1009
+ @hpxml_bldgs.each do |hpxml_bldg|
1010
+ hpxml_bldg.batteries.each do |battery|
1011
+ batteries << battery
1012
+ end
1013
+ end
1014
+ next if batteries.empty?
1015
+
1016
+ if batteries.size > 1
1017
+ # When modeling individual dwelling units, OS-HPXML only allows a single battery
1018
+ # When modeling whole SFA/MF buildings, OS-HPXML does not currently allow batteries
1019
+ fail 'Unexpected error.'
1020
+ end
1021
+
1022
+ battery = batteries[0]
1023
+
1024
+ elcd = @model.getElectricLoadCenterDistributions.find { |elcd| elcd.additionalProperties.getFeatureAsString('HPXML_ID').to_s == battery.id }
1025
+ next if elcd.nil?
1026
+
1027
+ resilience_frequency = 'timestep'
1028
+ ts_per_hr = @model.getTimestep.numberOfTimestepsPerHour
1029
+ if args[:timeseries_frequency] != 'timestep'
1030
+ resilience_frequency = 'hourly'
1031
+ ts_per_hr = 1
1032
+ end
1033
+
1034
+ vars = ['Electric Storage Charge Fraction']
1035
+ keys = resilience.variables.select { |v| v[2] == vars[0] }.map { |v| v[1] }
1036
+ batt_soc = get_report_variable_data_timeseries(keys, vars, 1, 0, resilience_frequency)
1037
+
1038
+ vars = ['Other Equipment Electricity Energy']
1039
+ keys = resilience.variables.select { |v| v[2] == vars[0] }.map { |v| v[1] }
1040
+ batt_loss = get_report_variable_data_timeseries(keys, vars, UnitConversions.convert(1.0, 'J', 'kWh'), 0, resilience_frequency)
1041
+
1042
+ min_soc = elcd.minimumStorageStateofChargeFraction
1043
+ batt_kw = battery.rated_power_output / 1000.0
1044
+ batt_roundtrip_eff = battery.round_trip_efficiency
1045
+ batt_kwh = Battery.get_usable_capacity_kWh(battery)
1046
+
1047
+ batt_soc_kwh = batt_soc.map { |soc| soc - min_soc }.map { |soc| soc * batt_kwh }
1048
+ elec_prod = get_report_meter_data_timeseries(['ElectricityProduced:Facility'], UnitConversions.convert(1.0, 'J', 'kWh'), 0, resilience_frequency)
1049
+ elec_stor = get_report_meter_data_timeseries(['ElectricStorage:ElectricityProduced'], UnitConversions.convert(1.0, 'J', 'kWh'), 0, resilience_frequency)
1050
+ elec_prod = elec_prod.zip(elec_stor).map { |x, y| -1 * (x - y) }
1051
+ elec = get_report_meter_data_timeseries(['Electricity:Facility'], UnitConversions.convert(1.0, 'J', 'kWh'), 0, resilience_frequency)
1052
+ crit_load = elec.zip(elec_prod, batt_loss).map { |x, y, z| x + y + z }
1053
+
1054
+ resilience_timeseries = []
1055
+ n_timesteps = crit_load.size
1056
+ (0...n_timesteps).each do |init_time_step|
1057
+ resilience_timeseries << get_resilience_timeseries(init_time_step, batt_kwh, batt_kw, batt_soc_kwh[init_time_step], crit_load, batt_roundtrip_eff, n_timesteps, ts_per_hr)
1058
+ end
1059
+
1060
+ resilience.annual_output = resilience_timeseries.sum(0.0) / resilience_timeseries.size
1061
+
1062
+ next unless args[:include_timeseries_resilience]
1063
+
1064
+ resilience.timeseries_output = resilience_timeseries
1065
+
1066
+ # Aggregate up from hourly to the desired timeseries frequency
1067
+ if ['daily', 'monthly'].include? args[:timeseries_frequency]
1068
+ resilience.timeseries_output = rollup_timeseries_output_to_daily_or_monthly(resilience.timeseries_output, args[:timeseries_frequency], true)
1069
+ end
1070
+ end
1071
+
875
1072
  # Zone temperatures
876
1073
  if args[:include_timeseries_zone_temperatures]
1074
+ def sanitize_name(name)
1075
+ return name.gsub('_', ' ').split.map(&:capitalize).join(' ')
1076
+ end
1077
+
1078
+ # Zone temperatures
877
1079
  zone_names = []
878
- scheduled_temperature_names = []
879
1080
  @model.getThermalZones.each do |zone|
880
- if zone.floorArea > 1
881
- zone_names << zone.name.to_s.upcase
882
- end
883
- end
884
- @model.getScheduleConstants.each do |schedule|
885
- next unless [HPXML::LocationOtherHeatedSpace, HPXML::LocationOtherMultifamilyBufferSpace, HPXML::LocationOtherNonFreezingSpace,
886
- HPXML::LocationOtherHousingUnit, HPXML::LocationExteriorWall, HPXML::LocationUnderSlab].include? schedule.name.to_s
1081
+ next if zone.floorArea <= 1
887
1082
 
888
- scheduled_temperature_names << schedule.name.to_s.upcase
1083
+ zone_names << zone.name.to_s.upcase
889
1084
  end
890
1085
  zone_names.sort.each do |zone_name|
891
1086
  @zone_temps[zone_name] = ZoneTemp.new
892
- @zone_temps[zone_name].name = "Temperature: #{zone_name.split.map(&:capitalize).join(' ')}"
1087
+ @zone_temps[zone_name].name = "Temperature: #{sanitize_name(zone_name)}"
893
1088
  @zone_temps[zone_name].timeseries_units = 'F'
894
1089
  @zone_temps[zone_name].timeseries_output = get_report_variable_data_timeseries([zone_name], ['Zone Mean Air Temperature'], 9.0 / 5.0, 32.0, args[:timeseries_frequency])
895
1090
  end
896
- scheduled_temperature_names.sort.each do |scheduled_temperature_name|
897
- @zone_temps[scheduled_temperature_name] = ZoneTemp.new
898
- @zone_temps[scheduled_temperature_name].name = "Temperature: #{scheduled_temperature_name.split.map(&:capitalize).join(' ')}"
899
- @zone_temps[scheduled_temperature_name].timeseries_units = 'F'
900
- @zone_temps[scheduled_temperature_name].timeseries_output = get_report_variable_data_timeseries([scheduled_temperature_name], ['Schedule Value'], 9.0 / 5.0, 32.0, args[:timeseries_frequency])
1091
+
1092
+ # Scheduled temperatures
1093
+ [HPXML::LocationOtherHeatedSpace, HPXML::LocationOtherMultifamilyBufferSpace,
1094
+ HPXML::LocationOtherNonFreezingSpace, HPXML::LocationOtherHousingUnit,
1095
+ HPXML::LocationExteriorWall, HPXML::LocationUnderSlab].each do |sch_location|
1096
+ @model.getScheduleConstants.each do |schedule|
1097
+ next unless schedule.additionalProperties.getFeatureAsString('ObjectType').to_s == sch_location
1098
+
1099
+ sch_name = schedule.name.to_s.upcase
1100
+ @zone_temps[sch_name] = ZoneTemp.new
1101
+ @zone_temps[sch_name].name = "Temperature: #{sanitize_name(sch_name)}"
1102
+ @zone_temps[sch_name].timeseries_units = 'F'
1103
+ @zone_temps[sch_name].timeseries_output = get_report_variable_data_timeseries([sch_name], ['Schedule Value'], 9.0 / 5.0, 32.0, args[:timeseries_frequency])
1104
+
1105
+ break
1106
+ end
901
1107
  end
902
- { 'Heating Setpoint' => 'Zone Thermostat Heating Setpoint Temperature',
903
- 'Cooling Setpoint' => 'Zone Thermostat Cooling Setpoint Temperature' }.each do |sp_name, sp_var|
904
- @zone_temps[sp_name] = ZoneTemp.new
905
- @zone_temps[sp_name].name = "Temperature: #{sp_name}"
906
- @zone_temps[sp_name].timeseries_units = 'F'
907
- @zone_temps[sp_name].timeseries_output = get_report_variable_data_timeseries([HPXML::LocationLivingSpace.upcase], [sp_var], 9.0 / 5.0, 32.0, args[:timeseries_frequency])
1108
+
1109
+ # Heating Setpoints
1110
+ heated_zones = eval(@model.getBuilding.additionalProperties.getFeatureAsString('heated_zones').get)
1111
+ heated_zones.each do |heated_zone|
1112
+ var_name = 'Temperature: Heating Setpoint'
1113
+ if building_id == 'ALL'
1114
+ unit_num = @model.getThermalZones.find { |z| z.name.to_s == heated_zone }.spaces[0].buildingUnit.get.additionalProperties.getFeatureAsInteger('unit_num').get
1115
+ var_name = "Temperature: Unit#{unit_num} Heating Setpoint"
1116
+ end
1117
+ @zone_temps["#{heated_zone} Heating Setpoint"] = ZoneTemp.new
1118
+ @zone_temps["#{heated_zone} Heating Setpoint"].name = var_name
1119
+ @zone_temps["#{heated_zone} Heating Setpoint"].timeseries_units = 'F'
1120
+ @zone_temps["#{heated_zone} Heating Setpoint"].timeseries_output = get_report_variable_data_timeseries([heated_zone.upcase], ['Zone Thermostat Heating Setpoint Temperature'], 9.0 / 5.0, 32.0, args[:timeseries_frequency])
1121
+ end
1122
+
1123
+ # Cooling Setpoints
1124
+ cooled_zones = eval(@model.getBuilding.additionalProperties.getFeatureAsString('cooled_zones').get)
1125
+ cooled_zones.each do |cooled_zone|
1126
+ var_name = 'Temperature: Cooling Setpoint'
1127
+ if building_id == 'ALL'
1128
+ unit_num = @model.getThermalZones.find { |z| z.name.to_s == cooled_zone }.spaces[0].buildingUnit.get.additionalProperties.getFeatureAsInteger('unit_num').get
1129
+ var_name = "Temperature: Unit#{unit_num} Cooling Setpoint"
1130
+ end
1131
+ @zone_temps["#{cooled_zone} Cooling Setpoint"] = ZoneTemp.new
1132
+ @zone_temps["#{cooled_zone} Cooling Setpoint"].name = var_name
1133
+ @zone_temps["#{cooled_zone} Cooling Setpoint"].timeseries_units = 'F'
1134
+ @zone_temps["#{cooled_zone} Cooling Setpoint"].timeseries_output = get_report_variable_data_timeseries([cooled_zone.upcase], ['Zone Thermostat Cooling Setpoint Temperature'], 9.0 / 5.0, 32.0, args[:timeseries_frequency])
908
1135
  end
909
1136
  end
910
1137
 
911
1138
  # Airflows
912
1139
  if args[:include_timeseries_airflows]
913
1140
  @airflows.each do |_airflow_type, airflow|
914
- airflow.timeseries_output = get_report_variable_data_timeseries(['EMS'], airflow.ems_variables.map { |var| "#{var}_timeseries_outvar" }, UnitConversions.convert(1.0, 'm^3/s', 'cfm'), 0, args[:timeseries_frequency])
1141
+ # FUTURE: This works but may incur a performance penalty.
1142
+ # Switch to creating a single EMS program that sums the airflows from
1143
+ # the individual dwelling units and then just grab those outputs here.
1144
+ for i in 0..@hpxml_bldgs.size - 1
1145
+ unit_prefix = @hpxml_bldgs.size > 1 ? "unit#{i + 1}_" : ''
1146
+ unit_multiplier = @hpxml_bldgs[i].building_construction.number_of_units
1147
+ values = get_report_variable_data_timeseries(['EMS'], ["#{unit_prefix}#{airflow.ems_variable}_timeseries_outvar"], UnitConversions.convert(unit_multiplier, 'm^3/s', 'cfm'), 0, args[:timeseries_frequency])
1148
+ if airflow.timeseries_output.empty?
1149
+ airflow.timeseries_output = values
1150
+ else
1151
+ airflow.timeseries_output = airflow.timeseries_output.zip(values).map { |x, y| x + y }
1152
+ end
1153
+ end
915
1154
  end
916
1155
  end
917
1156
 
@@ -946,7 +1185,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
946
1185
  kwh_to_mwh = UnitConversions.convert(1.0, 'kWh', 'MWh')
947
1186
 
948
1187
  # Calculate for each scenario
949
- @hpxml.header.emissions_scenarios.each do |scenario|
1188
+ @hpxml_header.emissions_scenarios.each do |scenario|
950
1189
  key = [scenario.emissions_type, scenario.name]
951
1190
 
952
1191
  # Get hourly electricity factors
@@ -1000,7 +1239,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1000
1239
 
1001
1240
  # Calculate timeseries emissions for end use
1002
1241
 
1003
- if args[:timeseries_frequency] == 'timestep' && @hpxml.header.timestep != 60
1242
+ if args[:timeseries_frequency] == 'timestep' && @hpxml_header.timestep != 60
1004
1243
  timeseries_elec = end_use.timeseries_output_by_system.values.transpose.map(&:sum).map { |x| x * kwh_to_mwh }
1005
1244
  else
1006
1245
  # Need to perform calculations hourly at a minimum
@@ -1008,7 +1247,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1008
1247
  end
1009
1248
 
1010
1249
  if args[:timeseries_frequency] == 'timestep'
1011
- n_timesteps_per_hour = Integer(60.0 / @hpxml.header.timestep)
1250
+ n_timesteps_per_hour = Integer(60.0 / @hpxml_header.timestep)
1012
1251
  timeseries_elec_factors = hourly_elec_factors.flat_map { |y| [y] * n_timesteps_per_hour }
1013
1252
  else
1014
1253
  timeseries_elec_factors = hourly_elec_factors.dup
@@ -1018,26 +1257,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1018
1257
  @emissions[key].timeseries_output_by_end_use[eu_key] = timeseries_elec.zip(timeseries_elec_factors).map { |n, f| n * f * elec_units_mult }
1019
1258
 
1020
1259
  # Aggregate up from hourly to the desired timeseries frequency
1021
- next unless ['daily', 'monthly'].include? args[:timeseries_frequency]
1022
-
1023
- if args[:timeseries_frequency] == 'daily'
1024
- n_hours_per_period = [24] * (sim_end_day_of_year - sim_start_day_of_year + 1)
1025
- elsif args[:timeseries_frequency] == 'monthly'
1026
- n_days_per_month = Constants.NumDaysInMonths(year)
1027
- n_days_per_period = n_days_per_month[@hpxml.header.sim_begin_month - 1..@hpxml.header.sim_end_month - 1]
1028
- n_days_per_period[0] -= @hpxml.header.sim_begin_day - 1
1029
- n_days_per_period[-1] = @hpxml.header.sim_end_day
1030
- n_hours_per_period = n_days_per_period.map { |x| x * 24 }
1031
- end
1032
- fail 'Unexpected failure for emissions calculations.' if n_hours_per_period.sum != @emissions[key].timeseries_output_by_end_use[eu_key].size
1033
-
1034
- timeseries_output = []
1035
- start_hour = 0
1036
- n_hours_per_period.each do |n_hours|
1037
- timeseries_output << @emissions[key].timeseries_output_by_end_use[eu_key][start_hour..start_hour + n_hours - 1].sum()
1038
- start_hour += n_hours
1260
+ if ['daily', 'monthly'].include? args[:timeseries_frequency]
1261
+ @emissions[key].timeseries_output_by_end_use[eu_key] = rollup_timeseries_output_to_daily_or_monthly(@emissions[key].timeseries_output_by_end_use[eu_key], args[:timeseries_frequency])
1039
1262
  end
1040
- @emissions[key].timeseries_output_by_end_use[eu_key] = timeseries_output
1041
1263
  end
1042
1264
 
1043
1265
  # Calculate emissions for fossil fuels
@@ -1112,8 +1334,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1112
1334
  end
1113
1335
 
1114
1336
  def get_sim_times_of_year(year)
1115
- sim_start_day_of_year = Schedule.get_day_num_from_month_day(year, @hpxml.header.sim_begin_month, @hpxml.header.sim_begin_day)
1116
- sim_end_day_of_year = Schedule.get_day_num_from_month_day(year, @hpxml.header.sim_end_month, @hpxml.header.sim_end_day)
1337
+ sim_start_day_of_year = Schedule.get_day_num_from_month_day(year, @hpxml_header.sim_begin_month, @hpxml_header.sim_begin_day)
1338
+ sim_end_day_of_year = Schedule.get_day_num_from_month_day(year, @hpxml_header.sim_end_month, @hpxml_header.sim_end_day)
1117
1339
  sim_start_hour = (sim_start_day_of_year - 1) * 24
1118
1340
  sim_end_hour = sim_end_day_of_year * 24 - 1
1119
1341
  return sim_start_day_of_year, sim_end_day_of_year, sim_start_hour, sim_end_hour
@@ -1137,7 +1359,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1137
1359
 
1138
1360
  # Check if simulation successful
1139
1361
  all_total = @fuels.values.map { |x| x.annual_output.to_f }.sum(0.0)
1140
- if (all_total == 0) && (@hpxml.total_fraction_cool_load_served + @hpxml.total_fraction_heat_load_served > 0)
1362
+ total_fraction_cool_load_served = @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.total_fraction_cool_load_served }.sum(0.0)
1363
+ total_fraction_heat_load_served = @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.total_fraction_heat_load_served }.sum(0.0)
1364
+ if (all_total == 0) && (total_fraction_cool_load_served + total_fraction_heat_load_served > 0)
1141
1365
  runner.registerError('Simulation unsuccessful.')
1142
1366
  return false
1143
1367
  elsif all_total.infinite?
@@ -1159,10 +1383,25 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1159
1383
  meter_fuel_total += meter_elec_produced
1160
1384
  end
1161
1385
 
1162
- if (sum_categories - meter_fuel_total).abs > tol
1163
- runner.registerError("#{fuel_type} category end uses (#{sum_categories.round(3)}) do not sum to total (#{meter_fuel_total.round(3)}).")
1164
- return false
1165
- end
1386
+ next unless (sum_categories - meter_fuel_total).abs > tol
1387
+
1388
+ runner.registerError("#{fuel_type} category end uses (#{sum_categories.round(3)}) do not sum to total (#{meter_fuel_total.round(3)}).")
1389
+ return false
1390
+ end
1391
+
1392
+ # Check sum of system use outputs match end use outputs
1393
+ system_use_sums = {}
1394
+ @system_uses.each do |key, system_use|
1395
+ _sys_id, eu_key = key
1396
+ system_use_sums[eu_key] = 0 if system_use_sums[eu_key].nil?
1397
+ system_use_sums[eu_key] += system_use.annual_output
1398
+ end
1399
+ system_use_sums.each do |eu_key, systems_sum|
1400
+ end_use_total = @end_uses[eu_key].annual_output.to_f
1401
+ next unless (systems_sum - end_use_total).abs > tol
1402
+
1403
+ runner.registerError("System uses (#{systems_sum.round(3)}) do not sum to total (#{end_use_total.round(3)}) for End Use: #{eu_key.join(': ')}.")
1404
+ return false
1166
1405
  end
1167
1406
 
1168
1407
  # Check sum of timeseries outputs match annual outputs
@@ -1196,8 +1435,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1196
1435
  else
1197
1436
  # Note: Make sure to round outputs with sufficient resolution for the worst case -- i.e., 1 day instead of a full year.
1198
1437
  n_digits = 3 # Default for annual (or near-annual) data
1199
- sim_n_days = (Schedule.get_day_num_from_month_day(2000, @hpxml.header.sim_end_month, @hpxml.header.sim_end_day) -
1200
- Schedule.get_day_num_from_month_day(2000, @hpxml.header.sim_begin_month, @hpxml.header.sim_begin_day))
1438
+ sim_n_days = (Schedule.get_day_num_from_month_day(2000, @hpxml_header.sim_end_month, @hpxml_header.sim_end_day) -
1439
+ Schedule.get_day_num_from_month_day(2000, @hpxml_header.sim_begin_month, @hpxml_header.sim_begin_day))
1201
1440
  if sim_n_days <= 10 # 10 days or less; add two decimal places
1202
1441
  n_digits += 2
1203
1442
  elsif sim_n_days <= 100 # 100 days or less; add one decimal place
@@ -1335,6 +1574,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1335
1574
  results_out << [line_break]
1336
1575
  end
1337
1576
 
1577
+ # Resilience
1578
+ if args[:include_annual_resilience]
1579
+ @resilience.each do |_type, resilience|
1580
+ results_out << ["#{resilience.name} (#{resilience.annual_units})", resilience.annual_output.to_f.round(n_digits)]
1581
+ end
1582
+ results_out << [line_break]
1583
+ end
1584
+
1338
1585
  # Sizing data
1339
1586
  if args[:include_annual_hvac_summary]
1340
1587
  results_out = append_sizing_results(results_out, line_break)
@@ -1374,25 +1621,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1374
1621
  def append_sizing_results(results_out, line_break)
1375
1622
  # Summary HVAC capacities
1376
1623
  htg_cap, clg_cap, hp_backup_cap = 0.0, 0.0, 0.0
1377
- @hpxml.hvac_systems.each do |hvac_system|
1378
- if hvac_system.is_a? HPXML::HeatingSystem
1379
- next if hvac_system.is_heat_pump_backup_system
1380
-
1381
- htg_cap += hvac_system.heating_capacity.to_f
1382
- elsif hvac_system.is_a? HPXML::CoolingSystem
1383
- clg_cap += hvac_system.cooling_capacity.to_f
1384
- if hvac_system.has_integrated_heating
1385
- htg_cap += hvac_system.integrated_heating_system_capacity.to_f
1386
- end
1387
- elsif hvac_system.is_a? HPXML::HeatPump
1388
- htg_cap += hvac_system.heating_capacity.to_f
1389
- clg_cap += hvac_system.cooling_capacity.to_f
1390
- if hvac_system.backup_type == HPXML::HeatPumpBackupTypeIntegrated
1391
- hp_backup_cap += hvac_system.backup_heating_capacity.to_f
1392
- elsif hvac_system.backup_type == HPXML::HeatPumpBackupTypeSeparate
1393
- hp_backup_cap += hvac_system.backup_system.heating_capacity.to_f
1394
- end
1395
- end
1624
+ @hpxml_bldgs.each do |hpxml_bldg|
1625
+ capacities = Outputs.get_total_hvac_capacities(hpxml_bldg)
1626
+ htg_cap += capacities[0]
1627
+ clg_cap += capacities[1]
1628
+ hp_backup_cap += capacities[2]
1396
1629
  end
1397
1630
  results_out << ['HVAC Capacity: Heating (Btu/h)', htg_cap.round(1)]
1398
1631
  results_out << ['HVAC Capacity: Cooling (Btu/h)', clg_cap.round(1)]
@@ -1400,38 +1633,38 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1400
1633
 
1401
1634
  # HVAC design temperatures
1402
1635
  results_out << [line_break]
1403
- results_out << ['HVAC Design Temperature: Heating (F)', @hpxml.header.manualj_heating_design_temp.round(2)]
1404
- results_out << ['HVAC Design Temperature: Cooling (F)', @hpxml.header.manualj_cooling_design_temp.round(2)]
1636
+ results_out << ['HVAC Design Temperature: Heating (F)', (@hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.header.manualj_heating_design_temp }.sum(0.0) / @hpxml_bldgs.size).round(2)]
1637
+ results_out << ['HVAC Design Temperature: Cooling (F)', (@hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.header.manualj_cooling_design_temp }.sum(0.0) / @hpxml_bldgs.size).round(2)]
1405
1638
 
1406
1639
  # HVAC design loads
1407
1640
  results_out << [line_break]
1408
- results_out << ['HVAC Design Load: Heating: Total (Btu/h)', @hpxml.hvac_plant.hdl_total.round(1)]
1409
- results_out << ['HVAC Design Load: Heating: Ducts (Btu/h)', @hpxml.hvac_plant.hdl_ducts.round(1)]
1410
- results_out << ['HVAC Design Load: Heating: Windows (Btu/h)', @hpxml.hvac_plant.hdl_windows.round(1)]
1411
- results_out << ['HVAC Design Load: Heating: Skylights (Btu/h)', @hpxml.hvac_plant.hdl_skylights.round(1)]
1412
- results_out << ['HVAC Design Load: Heating: Doors (Btu/h)', @hpxml.hvac_plant.hdl_doors.round(1)]
1413
- results_out << ['HVAC Design Load: Heating: Walls (Btu/h)', @hpxml.hvac_plant.hdl_walls.round(1)]
1414
- results_out << ['HVAC Design Load: Heating: Roofs (Btu/h)', @hpxml.hvac_plant.hdl_roofs.round(1)]
1415
- results_out << ['HVAC Design Load: Heating: Floors (Btu/h)', @hpxml.hvac_plant.hdl_floors.round(1)]
1416
- results_out << ['HVAC Design Load: Heating: Slabs (Btu/h)', @hpxml.hvac_plant.hdl_slabs.round(1)]
1417
- results_out << ['HVAC Design Load: Heating: Ceilings (Btu/h)', @hpxml.hvac_plant.hdl_ceilings.round(1)]
1418
- results_out << ['HVAC Design Load: Heating: Infiltration/Ventilation (Btu/h)', @hpxml.hvac_plant.hdl_infilvent.round(1)]
1419
- results_out << ['HVAC Design Load: Cooling Sensible: Total (Btu/h)', @hpxml.hvac_plant.cdl_sens_total.round(1)]
1420
- results_out << ['HVAC Design Load: Cooling Sensible: Ducts (Btu/h)', @hpxml.hvac_plant.cdl_sens_ducts.round(1)]
1421
- results_out << ['HVAC Design Load: Cooling Sensible: Windows (Btu/h)', @hpxml.hvac_plant.cdl_sens_windows.round(1)]
1422
- results_out << ['HVAC Design Load: Cooling Sensible: Skylights (Btu/h)', @hpxml.hvac_plant.cdl_sens_skylights.round(1)]
1423
- results_out << ['HVAC Design Load: Cooling Sensible: Doors (Btu/h)', @hpxml.hvac_plant.cdl_sens_doors.round(1)]
1424
- results_out << ['HVAC Design Load: Cooling Sensible: Walls (Btu/h)', @hpxml.hvac_plant.cdl_sens_walls.round(1)]
1425
- results_out << ['HVAC Design Load: Cooling Sensible: Roofs (Btu/h)', @hpxml.hvac_plant.cdl_sens_roofs.round(1)]
1426
- results_out << ['HVAC Design Load: Cooling Sensible: Floors (Btu/h)', @hpxml.hvac_plant.cdl_sens_floors.round(1)]
1427
- results_out << ['HVAC Design Load: Cooling Sensible: Slabs (Btu/h)', @hpxml.hvac_plant.cdl_sens_slabs.round(1)]
1428
- results_out << ['HVAC Design Load: Cooling Sensible: Ceilings (Btu/h)', @hpxml.hvac_plant.cdl_sens_ceilings.round(1)]
1429
- results_out << ['HVAC Design Load: Cooling Sensible: Infiltration/Ventilation (Btu/h)', @hpxml.hvac_plant.cdl_sens_infilvent.round(1)]
1430
- results_out << ['HVAC Design Load: Cooling Sensible: Internal Gains (Btu/h)', @hpxml.hvac_plant.cdl_sens_intgains.round(1)]
1431
- results_out << ['HVAC Design Load: Cooling Latent: Total (Btu/h)', @hpxml.hvac_plant.cdl_lat_total.round(1)]
1432
- results_out << ['HVAC Design Load: Cooling Latent: Ducts (Btu/h)', @hpxml.hvac_plant.cdl_lat_ducts.round(1)]
1433
- results_out << ['HVAC Design Load: Cooling Latent: Infiltration/Ventilation (Btu/h)', @hpxml.hvac_plant.cdl_lat_infilvent.round(1)]
1434
- results_out << ['HVAC Design Load: Cooling Latent: Internal Gains (Btu/h)', @hpxml.hvac_plant.cdl_lat_intgains.round(1)]
1641
+ results_out << ['HVAC Design Load: Heating: Total (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_total * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1642
+ results_out << ['HVAC Design Load: Heating: Ducts (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_ducts * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1643
+ results_out << ['HVAC Design Load: Heating: Windows (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_windows * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1644
+ results_out << ['HVAC Design Load: Heating: Skylights (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_skylights * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1645
+ results_out << ['HVAC Design Load: Heating: Doors (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_doors * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1646
+ results_out << ['HVAC Design Load: Heating: Walls (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_walls * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1647
+ results_out << ['HVAC Design Load: Heating: Roofs (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_roofs * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1648
+ results_out << ['HVAC Design Load: Heating: Floors (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_floors * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1649
+ results_out << ['HVAC Design Load: Heating: Slabs (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_slabs * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1650
+ results_out << ['HVAC Design Load: Heating: Ceilings (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_ceilings * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1651
+ results_out << ['HVAC Design Load: Heating: Infiltration/Ventilation (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.hdl_infilvent * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1652
+ results_out << ['HVAC Design Load: Cooling Sensible: Total (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_total * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1653
+ results_out << ['HVAC Design Load: Cooling Sensible: Ducts (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_ducts * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1654
+ results_out << ['HVAC Design Load: Cooling Sensible: Windows (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_windows * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1655
+ results_out << ['HVAC Design Load: Cooling Sensible: Skylights (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_skylights * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1656
+ results_out << ['HVAC Design Load: Cooling Sensible: Doors (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_doors * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1657
+ results_out << ['HVAC Design Load: Cooling Sensible: Walls (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_walls * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1658
+ results_out << ['HVAC Design Load: Cooling Sensible: Roofs (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_roofs * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1659
+ results_out << ['HVAC Design Load: Cooling Sensible: Floors (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_floors * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1660
+ results_out << ['HVAC Design Load: Cooling Sensible: Slabs (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_slabs * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1661
+ results_out << ['HVAC Design Load: Cooling Sensible: Ceilings (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_ceilings * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1662
+ results_out << ['HVAC Design Load: Cooling Sensible: Infiltration/Ventilation (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_infilvent * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1663
+ results_out << ['HVAC Design Load: Cooling Sensible: Internal Gains (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_sens_intgains * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1664
+ results_out << ['HVAC Design Load: Cooling Latent: Total (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_lat_total * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1665
+ results_out << ['HVAC Design Load: Cooling Latent: Ducts (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_lat_ducts * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1666
+ results_out << ['HVAC Design Load: Cooling Latent: Infiltration/Ventilation (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_lat_infilvent * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1667
+ results_out << ['HVAC Design Load: Cooling Latent: Internal Gains (Btu/h)', @hpxml_bldgs.map { |hpxml_bldg| hpxml_bldg.hvac_plant.cdl_lat_intgains * hpxml_bldg.building_construction.number_of_units }.sum(0.0).round(1)]
1435
1668
 
1436
1669
  return results_out
1437
1670
  end
@@ -1453,9 +1686,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1453
1686
  # Note: Make sure to round outputs with sufficient resolution for the worst case -- i.e., 1 minute date instead of hourly data.
1454
1687
  n_digits = 3 # Default for hourly (or longer) data
1455
1688
  if args[:timeseries_frequency] == 'timestep'
1456
- if @hpxml.header.timestep <= 2 # 2-minute timesteps or shorter; add two decimal places
1689
+ if @hpxml_header.timestep <= 2 # 2-minute timesteps or shorter; add two decimal places
1457
1690
  n_digits += 2
1458
- elsif @hpxml.header.timestep <= 15 # 15-minute timesteps or shorter; add one decimal place
1691
+ elsif @hpxml_header.timestep <= 15 # 15-minute timesteps or shorter; add one decimal place
1459
1692
  n_digits += 1
1460
1693
  end
1461
1694
  end
@@ -1577,6 +1810,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1577
1810
  else
1578
1811
  weather_data = []
1579
1812
  end
1813
+ if args[:include_timeseries_resilience]
1814
+ resilience_data = @resilience.values.select { |x| x.timeseries_output.sum(0.0) != 0 }.map { |x| [x.name, x.timeseries_units] + x.timeseries_output.map { |v| v.round(n_digits) } }
1815
+ else
1816
+ resilience_data = []
1817
+ end
1580
1818
 
1581
1819
  # EnergyPlus output variables
1582
1820
  if not @output_variables.empty?
@@ -1587,7 +1825,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1587
1825
 
1588
1826
  return if (total_energy_data.size + fuel_data.size + end_use_data.size + system_use_data.size + emissions_data.size + emission_fuel_data.size +
1589
1827
  emission_end_use_data.size + hot_water_use_data.size + total_loads_data.size + comp_loads_data.size + unmet_hours_data.size +
1590
- zone_temps_data.size + airflows_data.size + weather_data.size + output_variables_data.size) == 0
1828
+ zone_temps_data.size + airflows_data.size + weather_data.size + resilience_data.size + output_variables_data.size) == 0
1591
1829
 
1592
1830
  fail 'Unable to obtain timestamps.' if @timestamps.empty?
1593
1831
 
@@ -1595,7 +1833,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1595
1833
  # Assemble data
1596
1834
  data = data.zip(*timestamps2, *timestamps3, *total_energy_data, *fuel_data, *end_use_data, *system_use_data, *emissions_data,
1597
1835
  *emission_fuel_data, *emission_end_use_data, *hot_water_use_data, *total_loads_data, *comp_loads_data,
1598
- *unmet_hours_data, *zone_temps_data, *airflows_data, *weather_data, *output_variables_data)
1836
+ *unmet_hours_data, *zone_temps_data, *airflows_data, *weather_data, *resilience_data, *output_variables_data)
1599
1837
 
1600
1838
  # Error-check
1601
1839
  n_elements = []
@@ -1613,11 +1851,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1613
1851
  end
1614
1852
 
1615
1853
  # Add header per DataFileTemplate.pdf; see https://github.com/NREL/wex/wiki/DView
1616
- year = @hpxml.header.sim_calendar_year
1617
- start_day = Schedule.get_day_num_from_month_day(year, @hpxml.header.sim_begin_month, @hpxml.header.sim_begin_day)
1854
+ year = @hpxml_header.sim_calendar_year
1855
+ start_day = Schedule.get_day_num_from_month_day(year, @hpxml_header.sim_begin_month, @hpxml_header.sim_begin_day)
1618
1856
  start_hr = (start_day - 1) * 24
1619
1857
  if args[:timeseries_frequency] == 'timestep'
1620
- interval_hrs = @hpxml.header.timestep / 60.0
1858
+ interval_hrs = @hpxml_header.timestep / 60.0
1621
1859
  elsif args[:timeseries_frequency] == 'hourly'
1622
1860
  interval_hrs = 1.0
1623
1861
  elsif args[:timeseries_frequency] == 'daily'
@@ -1635,10 +1873,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1635
1873
 
1636
1874
  # Apply daylight savings
1637
1875
  if args[:timeseries_frequency] == 'timestep' || args[:timeseries_frequency] == 'hourly'
1638
- if @hpxml.header.dst_enabled
1876
+ if @hpxml_bldgs[0].dst_enabled
1639
1877
  dst_start_ix, dst_end_ix = get_dst_start_end_indexes(@timestamps, timestamps_dst)
1640
- dst_end_ix.downto(dst_start_ix + 1) do |i|
1641
- data[i + 1] = data[i]
1878
+ if !dst_start_ix.nil? && !dst_end_ix.nil?
1879
+ dst_end_ix.downto(dst_start_ix + 1) do |i|
1880
+ data[i + 1] = data[i]
1881
+ end
1642
1882
  end
1643
1883
  end
1644
1884
  end
@@ -1657,7 +1897,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1657
1897
 
1658
1898
  [total_energy_data, fuel_data, end_use_data, system_use_data, emissions_data, emission_fuel_data,
1659
1899
  emission_end_use_data, hot_water_use_data, total_loads_data, comp_loads_data, unmet_hours_data,
1660
- zone_temps_data, airflows_data, weather_data, output_variables_data].each do |d|
1900
+ zone_temps_data, airflows_data, weather_data, resilience_data, output_variables_data].each do |d|
1661
1901
  d.each do |o|
1662
1902
  grp, name = o[0].split(':', 2)
1663
1903
  h[grp] = {} if h[grp].nil?
@@ -1684,7 +1924,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1684
1924
  dst_end_ix = i if ts[0] == ts[1] && dst_end_ix.nil? && !dst_start_ix.nil?
1685
1925
  end
1686
1926
 
1687
- dst_end_ix = timestamps.size - 1 if dst_end_ix.nil? # run period ends before DST ends
1927
+ dst_end_ix = timestamps.size - 1 if dst_end_ix.nil? && !dst_start_ix.nil? # run period ends before DST ends
1688
1928
 
1689
1929
  return dst_start_ix, dst_end_ix
1690
1930
  end
@@ -1715,6 +1955,39 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1715
1955
  return val
1716
1956
  end
1717
1957
 
1958
+ def get_resilience_timeseries(init_time_step, batt_kwh, batt_kw, batt_soc_kwh, crit_load, batt_roundtrip_eff, n_timesteps, ts_per_hr)
1959
+ for i in 0...n_timesteps
1960
+ t = (init_time_step + i) % n_timesteps # for wrapping around end of year
1961
+ load_kw = crit_load[t]
1962
+
1963
+ # even if load_kw is negative, we return if batt_soc_kwh isn't charged at all
1964
+ return i / Float(ts_per_hr) if batt_soc_kwh <= 0
1965
+
1966
+ if load_kw < 0 # load is met with PV
1967
+ if batt_soc_kwh < batt_kwh # charge battery if there's room in the battery
1968
+ batt_soc_kwh += [
1969
+ batt_kwh - batt_soc_kwh, # room available
1970
+ batt_kw / batt_roundtrip_eff, # inverter capacity
1971
+ -load_kw * batt_roundtrip_eff, # excess energy
1972
+ ].min
1973
+ end
1974
+
1975
+ else # check if we can meet load with generator then storage
1976
+ if [batt_kw, batt_soc_kwh].min >= load_kw # battery can carry balance
1977
+ # prevent battery charge from going negative
1978
+ batt_soc_kwh = [0, batt_soc_kwh - load_kw / batt_roundtrip_eff].max
1979
+ load_kw = 0
1980
+ end
1981
+ end
1982
+
1983
+ if load_kw > 0 # failed to meet load in this time step
1984
+ return i / Float(ts_per_hr)
1985
+ end
1986
+ end
1987
+
1988
+ return n_timesteps / Float(ts_per_hr)
1989
+ end
1990
+
1718
1991
  def get_report_meter_data_timeseries(meter_names, unit_conv, unit_adder, timeseries_frequency)
1719
1992
  return [0.0] * @timestamps.size if meter_names.empty?
1720
1993
 
@@ -1846,18 +2119,19 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1846
2119
  end
1847
2120
  end
1848
2121
 
1849
- def create_all_object_variables_by_key
2122
+ def create_all_object_outputs_by_key
1850
2123
  @object_variables_by_key = {}
1851
2124
  return if @model.nil?
1852
2125
 
1853
2126
  @model.getModelObjects.sort.each do |object|
1854
2127
  next if object.to_AdditionalProperties.is_initialized
1855
2128
 
1856
- [EUT, HWT, LT].each do |class_name|
2129
+ [EUT, HWT, LT, RT].each do |class_name|
2130
+ vars_by_key = get_object_outputs_by_key(@model, object, class_name)
2131
+ next if vars_by_key.size == 0
2132
+
1857
2133
  sys_id = object.additionalProperties.getFeatureAsString('HPXML_ID')
1858
2134
  sys_id = sys_id.is_initialized ? sys_id.get : nil
1859
- vars_by_key = get_object_output_variables_by_key(@model, object, sys_id, class_name)
1860
- next if vars_by_key.size == 0
1861
2135
 
1862
2136
  vars_by_key.each do |key, output_vars|
1863
2137
  output_vars.each do |output_var|
@@ -1877,7 +2151,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1877
2151
  end
1878
2152
  end
1879
2153
 
1880
- def get_object_variables(class_name, key)
2154
+ def get_object_outputs(class_name, key)
1881
2155
  hash_key = [class_name, key]
1882
2156
  vars = @object_variables_by_key[hash_key]
1883
2157
  vars = [] if vars.nil?
@@ -1908,9 +2182,10 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1908
2182
  end
1909
2183
 
1910
2184
  class EndUse < BaseOutput
1911
- def initialize(variables: [], is_negative: false, is_storage: false)
2185
+ def initialize(outputs: [], is_negative: false, is_storage: false)
1912
2186
  super()
1913
- @variables = variables
2187
+ @variables = outputs.select { |o| !o[2].include?(':') }
2188
+ @meters = outputs.select { |o| o[2].include?(':') }
1914
2189
  @is_negative = is_negative
1915
2190
  @is_storage = is_storage
1916
2191
  @timeseries_output_by_system = {}
@@ -1919,7 +2194,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1919
2194
  @hourly_output = []
1920
2195
  @hourly_output_by_system = {}
1921
2196
  end
1922
- attr_accessor(:variables, :is_negative, :is_storage, :annual_output_by_system, :timeseries_output_by_system,
2197
+ attr_accessor(:variables, :meters, :is_negative, :is_storage, :annual_output_by_system, :timeseries_output_by_system,
1923
2198
  :hourly_output, :hourly_output_by_system)
1924
2199
  end
1925
2200
 
@@ -1938,13 +2213,22 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1938
2213
  end
1939
2214
 
1940
2215
  class HotWater < BaseOutput
1941
- def initialize(variables: [])
2216
+ def initialize(outputs: [])
1942
2217
  super()
1943
- @variables = variables
2218
+ @variables = outputs.select { |o| !o[2].include?(':') }
2219
+ @meters = outputs.select { |o| o[2].include?(':') }
1944
2220
  @timeseries_output_by_system = {}
1945
2221
  @annual_output_by_system = {}
1946
2222
  end
1947
- attr_accessor(:variables, :annual_output_by_system, :timeseries_output_by_system)
2223
+ attr_accessor(:variables, :meters, :annual_output_by_system, :timeseries_output_by_system)
2224
+ end
2225
+
2226
+ class Resilience < BaseOutput
2227
+ def initialize(variables: [])
2228
+ super()
2229
+ @variables = variables
2230
+ end
2231
+ attr_accessor(:variables)
1948
2232
  end
1949
2233
 
1950
2234
  class PeakFuel < BaseOutput
@@ -2008,12 +2292,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2008
2292
  end
2009
2293
 
2010
2294
  class Airflow < BaseOutput
2011
- def initialize(ems_program:, ems_variables:)
2295
+ def initialize(ems_program:, ems_variable:)
2012
2296
  super()
2013
2297
  @ems_program = ems_program
2014
- @ems_variables = ems_variables
2298
+ @ems_variable = ems_variable
2015
2299
  end
2016
- attr_accessor(:ems_program, :ems_variables)
2300
+ attr_accessor(:ems_program, :ems_variable)
2017
2301
  end
2018
2302
 
2019
2303
  class Weather < BaseOutput
@@ -2044,116 +2328,113 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2044
2328
 
2045
2329
  # End Uses
2046
2330
 
2047
- # NOTE: Some end uses are obtained from meters, others are rolled up from
2048
- # output variables so that we can have more control.
2049
-
2050
- create_all_object_variables_by_key()
2331
+ create_all_object_outputs_by_key()
2051
2332
 
2052
2333
  @end_uses = {}
2053
- @end_uses[[FT::Elec, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Heating]))
2054
- @end_uses[[FT::Elec, EUT::HeatingFanPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HeatingFanPump]))
2055
- @end_uses[[FT::Elec, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HeatingHeatPumpBackup]))
2056
- @end_uses[[FT::Elec, EUT::HeatingHeatPumpBackupFanPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HeatingHeatPumpBackupFanPump]))
2057
- @end_uses[[FT::Elec, EUT::Cooling]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Cooling]))
2058
- @end_uses[[FT::Elec, EUT::CoolingFanPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::CoolingFanPump]))
2059
- @end_uses[[FT::Elec, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HotWater]))
2060
- @end_uses[[FT::Elec, EUT::HotWaterRecircPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HotWaterRecircPump]))
2061
- @end_uses[[FT::Elec, EUT::HotWaterSolarThermalPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HotWaterSolarThermalPump]))
2062
- @end_uses[[FT::Elec, EUT::LightsInterior]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::LightsInterior]))
2063
- @end_uses[[FT::Elec, EUT::LightsGarage]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::LightsGarage]))
2064
- @end_uses[[FT::Elec, EUT::LightsExterior]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::LightsExterior]))
2065
- @end_uses[[FT::Elec, EUT::MechVent]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::MechVent]))
2066
- @end_uses[[FT::Elec, EUT::MechVentPreheat]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::MechVentPreheat]))
2067
- @end_uses[[FT::Elec, EUT::MechVentPrecool]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::MechVentPrecool]))
2068
- @end_uses[[FT::Elec, EUT::WholeHouseFan]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::WholeHouseFan]))
2069
- @end_uses[[FT::Elec, EUT::Refrigerator]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Refrigerator]))
2070
- @end_uses[[FT::Elec, EUT::Freezer]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Freezer]))
2071
- @end_uses[[FT::Elec, EUT::Dehumidifier]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Dehumidifier]))
2072
- @end_uses[[FT::Elec, EUT::Dishwasher]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Dishwasher]))
2073
- @end_uses[[FT::Elec, EUT::ClothesWasher]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::ClothesWasher]))
2074
- @end_uses[[FT::Elec, EUT::ClothesDryer]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::ClothesDryer]))
2075
- @end_uses[[FT::Elec, EUT::RangeOven]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::RangeOven]))
2076
- @end_uses[[FT::Elec, EUT::CeilingFan]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::CeilingFan]))
2077
- @end_uses[[FT::Elec, EUT::Television]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Television]))
2078
- @end_uses[[FT::Elec, EUT::PlugLoads]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::PlugLoads]))
2079
- @end_uses[[FT::Elec, EUT::Vehicle]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Vehicle]))
2080
- @end_uses[[FT::Elec, EUT::WellPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::WellPump]))
2081
- @end_uses[[FT::Elec, EUT::PoolHeater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::PoolHeater]))
2082
- @end_uses[[FT::Elec, EUT::PoolPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::PoolPump]))
2083
- @end_uses[[FT::Elec, EUT::HotTubHeater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HotTubHeater]))
2084
- @end_uses[[FT::Elec, EUT::HotTubPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HotTubPump]))
2085
- @end_uses[[FT::Elec, EUT::PV]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::PV]),
2334
+ @end_uses[[FT::Elec, EUT::Heating]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Heating]))
2335
+ @end_uses[[FT::Elec, EUT::HeatingFanPump]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::HeatingFanPump]))
2336
+ @end_uses[[FT::Elec, EUT::HeatingHeatPumpBackup]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::HeatingHeatPumpBackup]))
2337
+ @end_uses[[FT::Elec, EUT::HeatingHeatPumpBackupFanPump]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::HeatingHeatPumpBackupFanPump]))
2338
+ @end_uses[[FT::Elec, EUT::Cooling]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Cooling]))
2339
+ @end_uses[[FT::Elec, EUT::CoolingFanPump]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::CoolingFanPump]))
2340
+ @end_uses[[FT::Elec, EUT::HotWater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::HotWater]))
2341
+ @end_uses[[FT::Elec, EUT::HotWaterRecircPump]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::HotWaterRecircPump]))
2342
+ @end_uses[[FT::Elec, EUT::HotWaterSolarThermalPump]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::HotWaterSolarThermalPump]))
2343
+ @end_uses[[FT::Elec, EUT::LightsInterior]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::LightsInterior]))
2344
+ @end_uses[[FT::Elec, EUT::LightsGarage]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::LightsGarage]))
2345
+ @end_uses[[FT::Elec, EUT::LightsExterior]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::LightsExterior]))
2346
+ @end_uses[[FT::Elec, EUT::MechVent]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::MechVent]))
2347
+ @end_uses[[FT::Elec, EUT::MechVentPreheat]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::MechVentPreheat]))
2348
+ @end_uses[[FT::Elec, EUT::MechVentPrecool]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::MechVentPrecool]))
2349
+ @end_uses[[FT::Elec, EUT::WholeHouseFan]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::WholeHouseFan]))
2350
+ @end_uses[[FT::Elec, EUT::Refrigerator]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Refrigerator]))
2351
+ @end_uses[[FT::Elec, EUT::Freezer]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Freezer]))
2352
+ @end_uses[[FT::Elec, EUT::Dehumidifier]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Dehumidifier]))
2353
+ @end_uses[[FT::Elec, EUT::Dishwasher]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Dishwasher]))
2354
+ @end_uses[[FT::Elec, EUT::ClothesWasher]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::ClothesWasher]))
2355
+ @end_uses[[FT::Elec, EUT::ClothesDryer]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::ClothesDryer]))
2356
+ @end_uses[[FT::Elec, EUT::RangeOven]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::RangeOven]))
2357
+ @end_uses[[FT::Elec, EUT::CeilingFan]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::CeilingFan]))
2358
+ @end_uses[[FT::Elec, EUT::Television]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Television]))
2359
+ @end_uses[[FT::Elec, EUT::PlugLoads]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::PlugLoads]))
2360
+ @end_uses[[FT::Elec, EUT::Vehicle]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Vehicle]))
2361
+ @end_uses[[FT::Elec, EUT::WellPump]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::WellPump]))
2362
+ @end_uses[[FT::Elec, EUT::PoolHeater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::PoolHeater]))
2363
+ @end_uses[[FT::Elec, EUT::PoolPump]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::PoolPump]))
2364
+ @end_uses[[FT::Elec, EUT::PermanentSpaHeater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::PermanentSpaHeater]))
2365
+ @end_uses[[FT::Elec, EUT::PermanentSpaPump]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::PermanentSpaPump]))
2366
+ @end_uses[[FT::Elec, EUT::PV]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::PV]),
2086
2367
  is_negative: true)
2087
- @end_uses[[FT::Elec, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Generator]),
2368
+ @end_uses[[FT::Elec, EUT::Generator]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Generator]),
2088
2369
  is_negative: true)
2089
- @end_uses[[FT::Elec, EUT::Battery]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Battery]),
2370
+ @end_uses[[FT::Elec, EUT::Battery]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, EUT::Battery]),
2090
2371
  is_storage: true)
2091
- @end_uses[[FT::Gas, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::Heating]))
2092
- @end_uses[[FT::Gas, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::HeatingHeatPumpBackup]))
2093
- @end_uses[[FT::Gas, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::HotWater]))
2094
- @end_uses[[FT::Gas, EUT::ClothesDryer]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::ClothesDryer]))
2095
- @end_uses[[FT::Gas, EUT::RangeOven]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::RangeOven]))
2096
- @end_uses[[FT::Gas, EUT::MechVentPreheat]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::MechVentPreheat]))
2097
- @end_uses[[FT::Gas, EUT::PoolHeater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::PoolHeater]))
2098
- @end_uses[[FT::Gas, EUT::HotTubHeater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::HotTubHeater]))
2099
- @end_uses[[FT::Gas, EUT::Grill]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::Grill]))
2100
- @end_uses[[FT::Gas, EUT::Lighting]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::Lighting]))
2101
- @end_uses[[FT::Gas, EUT::Fireplace]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::Fireplace]))
2102
- @end_uses[[FT::Gas, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::Generator]))
2103
- @end_uses[[FT::Oil, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::Heating]))
2104
- @end_uses[[FT::Oil, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::HeatingHeatPumpBackup]))
2105
- @end_uses[[FT::Oil, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::HotWater]))
2106
- @end_uses[[FT::Oil, EUT::ClothesDryer]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::ClothesDryer]))
2107
- @end_uses[[FT::Oil, EUT::RangeOven]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::RangeOven]))
2108
- @end_uses[[FT::Oil, EUT::MechVentPreheat]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::MechVentPreheat]))
2109
- @end_uses[[FT::Oil, EUT::Grill]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::Grill]))
2110
- @end_uses[[FT::Oil, EUT::Lighting]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::Lighting]))
2111
- @end_uses[[FT::Oil, EUT::Fireplace]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::Fireplace]))
2112
- @end_uses[[FT::Oil, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::Oil, EUT::Generator]))
2113
- @end_uses[[FT::Propane, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::Heating]))
2114
- @end_uses[[FT::Propane, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::HeatingHeatPumpBackup]))
2115
- @end_uses[[FT::Propane, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::HotWater]))
2116
- @end_uses[[FT::Propane, EUT::ClothesDryer]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::ClothesDryer]))
2117
- @end_uses[[FT::Propane, EUT::RangeOven]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::RangeOven]))
2118
- @end_uses[[FT::Propane, EUT::MechVentPreheat]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::MechVentPreheat]))
2119
- @end_uses[[FT::Propane, EUT::Grill]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::Grill]))
2120
- @end_uses[[FT::Propane, EUT::Lighting]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::Lighting]))
2121
- @end_uses[[FT::Propane, EUT::Fireplace]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::Fireplace]))
2122
- @end_uses[[FT::Propane, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::Propane, EUT::Generator]))
2123
- @end_uses[[FT::WoodCord, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::Heating]))
2124
- @end_uses[[FT::WoodCord, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::HeatingHeatPumpBackup]))
2125
- @end_uses[[FT::WoodCord, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::HotWater]))
2126
- @end_uses[[FT::WoodCord, EUT::ClothesDryer]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::ClothesDryer]))
2127
- @end_uses[[FT::WoodCord, EUT::RangeOven]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::RangeOven]))
2128
- @end_uses[[FT::WoodCord, EUT::MechVentPreheat]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::MechVentPreheat]))
2129
- @end_uses[[FT::WoodCord, EUT::Grill]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::Grill]))
2130
- @end_uses[[FT::WoodCord, EUT::Lighting]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::Lighting]))
2131
- @end_uses[[FT::WoodCord, EUT::Fireplace]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::Fireplace]))
2132
- @end_uses[[FT::WoodCord, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodCord, EUT::Generator]))
2133
- @end_uses[[FT::WoodPellets, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::Heating]))
2134
- @end_uses[[FT::WoodPellets, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::HeatingHeatPumpBackup]))
2135
- @end_uses[[FT::WoodPellets, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::HotWater]))
2136
- @end_uses[[FT::WoodPellets, EUT::ClothesDryer]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::ClothesDryer]))
2137
- @end_uses[[FT::WoodPellets, EUT::RangeOven]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::RangeOven]))
2138
- @end_uses[[FT::WoodPellets, EUT::MechVentPreheat]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::MechVentPreheat]))
2139
- @end_uses[[FT::WoodPellets, EUT::Grill]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::Grill]))
2140
- @end_uses[[FT::WoodPellets, EUT::Lighting]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::Lighting]))
2141
- @end_uses[[FT::WoodPellets, EUT::Fireplace]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::Fireplace]))
2142
- @end_uses[[FT::WoodPellets, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::WoodPellets, EUT::Generator]))
2143
- @end_uses[[FT::Coal, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::Heating]))
2144
- @end_uses[[FT::Coal, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::HeatingHeatPumpBackup]))
2145
- @end_uses[[FT::Coal, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::HotWater]))
2146
- @end_uses[[FT::Coal, EUT::ClothesDryer]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::ClothesDryer]))
2147
- @end_uses[[FT::Coal, EUT::RangeOven]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::RangeOven]))
2148
- @end_uses[[FT::Coal, EUT::MechVentPreheat]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::MechVentPreheat]))
2149
- @end_uses[[FT::Coal, EUT::Grill]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::Grill]))
2150
- @end_uses[[FT::Coal, EUT::Lighting]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::Lighting]))
2151
- @end_uses[[FT::Coal, EUT::Fireplace]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::Fireplace]))
2152
- @end_uses[[FT::Coal, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::Generator]))
2372
+ @end_uses[[FT::Gas, EUT::Heating]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::Heating]))
2373
+ @end_uses[[FT::Gas, EUT::HeatingHeatPumpBackup]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::HeatingHeatPumpBackup]))
2374
+ @end_uses[[FT::Gas, EUT::HotWater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::HotWater]))
2375
+ @end_uses[[FT::Gas, EUT::ClothesDryer]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::ClothesDryer]))
2376
+ @end_uses[[FT::Gas, EUT::RangeOven]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::RangeOven]))
2377
+ @end_uses[[FT::Gas, EUT::MechVentPreheat]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::MechVentPreheat]))
2378
+ @end_uses[[FT::Gas, EUT::PoolHeater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::PoolHeater]))
2379
+ @end_uses[[FT::Gas, EUT::PermanentSpaHeater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::PermanentSpaHeater]))
2380
+ @end_uses[[FT::Gas, EUT::Grill]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::Grill]))
2381
+ @end_uses[[FT::Gas, EUT::Lighting]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::Lighting]))
2382
+ @end_uses[[FT::Gas, EUT::Fireplace]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::Fireplace]))
2383
+ @end_uses[[FT::Gas, EUT::Generator]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Gas, EUT::Generator]))
2384
+ @end_uses[[FT::Oil, EUT::Heating]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::Heating]))
2385
+ @end_uses[[FT::Oil, EUT::HeatingHeatPumpBackup]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::HeatingHeatPumpBackup]))
2386
+ @end_uses[[FT::Oil, EUT::HotWater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::HotWater]))
2387
+ @end_uses[[FT::Oil, EUT::ClothesDryer]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::ClothesDryer]))
2388
+ @end_uses[[FT::Oil, EUT::RangeOven]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::RangeOven]))
2389
+ @end_uses[[FT::Oil, EUT::MechVentPreheat]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::MechVentPreheat]))
2390
+ @end_uses[[FT::Oil, EUT::Grill]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::Grill]))
2391
+ @end_uses[[FT::Oil, EUT::Lighting]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::Lighting]))
2392
+ @end_uses[[FT::Oil, EUT::Fireplace]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::Fireplace]))
2393
+ @end_uses[[FT::Oil, EUT::Generator]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Oil, EUT::Generator]))
2394
+ @end_uses[[FT::Propane, EUT::Heating]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::Heating]))
2395
+ @end_uses[[FT::Propane, EUT::HeatingHeatPumpBackup]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::HeatingHeatPumpBackup]))
2396
+ @end_uses[[FT::Propane, EUT::HotWater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::HotWater]))
2397
+ @end_uses[[FT::Propane, EUT::ClothesDryer]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::ClothesDryer]))
2398
+ @end_uses[[FT::Propane, EUT::RangeOven]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::RangeOven]))
2399
+ @end_uses[[FT::Propane, EUT::MechVentPreheat]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::MechVentPreheat]))
2400
+ @end_uses[[FT::Propane, EUT::Grill]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::Grill]))
2401
+ @end_uses[[FT::Propane, EUT::Lighting]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::Lighting]))
2402
+ @end_uses[[FT::Propane, EUT::Fireplace]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::Fireplace]))
2403
+ @end_uses[[FT::Propane, EUT::Generator]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Propane, EUT::Generator]))
2404
+ @end_uses[[FT::WoodCord, EUT::Heating]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::Heating]))
2405
+ @end_uses[[FT::WoodCord, EUT::HeatingHeatPumpBackup]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::HeatingHeatPumpBackup]))
2406
+ @end_uses[[FT::WoodCord, EUT::HotWater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::HotWater]))
2407
+ @end_uses[[FT::WoodCord, EUT::ClothesDryer]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::ClothesDryer]))
2408
+ @end_uses[[FT::WoodCord, EUT::RangeOven]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::RangeOven]))
2409
+ @end_uses[[FT::WoodCord, EUT::MechVentPreheat]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::MechVentPreheat]))
2410
+ @end_uses[[FT::WoodCord, EUT::Grill]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::Grill]))
2411
+ @end_uses[[FT::WoodCord, EUT::Lighting]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::Lighting]))
2412
+ @end_uses[[FT::WoodCord, EUT::Fireplace]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::Fireplace]))
2413
+ @end_uses[[FT::WoodCord, EUT::Generator]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodCord, EUT::Generator]))
2414
+ @end_uses[[FT::WoodPellets, EUT::Heating]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::Heating]))
2415
+ @end_uses[[FT::WoodPellets, EUT::HeatingHeatPumpBackup]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::HeatingHeatPumpBackup]))
2416
+ @end_uses[[FT::WoodPellets, EUT::HotWater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::HotWater]))
2417
+ @end_uses[[FT::WoodPellets, EUT::ClothesDryer]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::ClothesDryer]))
2418
+ @end_uses[[FT::WoodPellets, EUT::RangeOven]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::RangeOven]))
2419
+ @end_uses[[FT::WoodPellets, EUT::MechVentPreheat]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::MechVentPreheat]))
2420
+ @end_uses[[FT::WoodPellets, EUT::Grill]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::Grill]))
2421
+ @end_uses[[FT::WoodPellets, EUT::Lighting]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::Lighting]))
2422
+ @end_uses[[FT::WoodPellets, EUT::Fireplace]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::Fireplace]))
2423
+ @end_uses[[FT::WoodPellets, EUT::Generator]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::WoodPellets, EUT::Generator]))
2424
+ @end_uses[[FT::Coal, EUT::Heating]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::Heating]))
2425
+ @end_uses[[FT::Coal, EUT::HeatingHeatPumpBackup]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::HeatingHeatPumpBackup]))
2426
+ @end_uses[[FT::Coal, EUT::HotWater]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::HotWater]))
2427
+ @end_uses[[FT::Coal, EUT::ClothesDryer]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::ClothesDryer]))
2428
+ @end_uses[[FT::Coal, EUT::RangeOven]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::RangeOven]))
2429
+ @end_uses[[FT::Coal, EUT::MechVentPreheat]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::MechVentPreheat]))
2430
+ @end_uses[[FT::Coal, EUT::Grill]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::Grill]))
2431
+ @end_uses[[FT::Coal, EUT::Lighting]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::Lighting]))
2432
+ @end_uses[[FT::Coal, EUT::Fireplace]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::Fireplace]))
2433
+ @end_uses[[FT::Coal, EUT::Generator]] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Coal, EUT::Generator]))
2153
2434
  if not called_from_outputs_method
2154
2435
  # Temporary end use to disaggregate 8760 GSHP shared loop pump energy into heating vs cooling.
2155
2436
  # This end use will not appear in output data/files.
2156
- @end_uses[[FT::Elec, 'TempGSHPSharedPump']] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, 'TempGSHPSharedPump']))
2437
+ @end_uses[[FT::Elec, 'TempGSHPSharedPump']] = EndUse.new(outputs: get_object_outputs(EUT, [FT::Elec, 'TempGSHPSharedPump']))
2157
2438
  end
2158
2439
  @end_uses.each do |key, end_use|
2159
2440
  fuel_type, end_use_type = key
@@ -2177,7 +2458,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2177
2458
  fuel.name = "Fuel Use: #{fuel_type}: Total"
2178
2459
  fuel.annual_units = 'MBtu'
2179
2460
  fuel.timeseries_units = get_timeseries_units_from_fuel_type(fuel_type)
2180
- if @end_uses.select { |key, end_use| key[0] == fuel_type && end_use.variables.size > 0 }.size == 0
2461
+ if @end_uses.select { |key, end_use| key[0] == fuel_type && end_use.variables.size + end_use.meters.size > 0 }.size == 0
2181
2462
  fuel.meters = []
2182
2463
  end
2183
2464
  end
@@ -2207,10 +2488,10 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2207
2488
 
2208
2489
  # Hot Water Uses
2209
2490
  @hot_water_uses = {}
2210
- @hot_water_uses[HWT::ClothesWasher] = HotWater.new(variables: get_object_variables(HWT, HWT::ClothesWasher))
2211
- @hot_water_uses[HWT::Dishwasher] = HotWater.new(variables: get_object_variables(HWT, HWT::Dishwasher))
2212
- @hot_water_uses[HWT::Fixtures] = HotWater.new(variables: get_object_variables(HWT, HWT::Fixtures))
2213
- @hot_water_uses[HWT::DistributionWaste] = HotWater.new(variables: get_object_variables(HWT, HWT::DistributionWaste))
2491
+ @hot_water_uses[HWT::ClothesWasher] = HotWater.new(outputs: get_object_outputs(HWT, HWT::ClothesWasher))
2492
+ @hot_water_uses[HWT::Dishwasher] = HotWater.new(outputs: get_object_outputs(HWT, HWT::Dishwasher))
2493
+ @hot_water_uses[HWT::Fixtures] = HotWater.new(outputs: get_object_outputs(HWT, HWT::Fixtures))
2494
+ @hot_water_uses[HWT::DistributionWaste] = HotWater.new(outputs: get_object_outputs(HWT, HWT::DistributionWaste))
2214
2495
 
2215
2496
  @hot_water_uses.each do |hot_water_type, hot_water|
2216
2497
  hot_water.name = "Hot Water: #{hot_water_type}"
@@ -2218,10 +2499,23 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2218
2499
  hot_water.timeseries_units = 'gal'
2219
2500
  end
2220
2501
 
2502
+ # Resilience
2503
+ @resilience = {}
2504
+ @resilience[RT::Battery] = Resilience.new(variables: get_object_outputs(RT, RT::Battery))
2505
+
2506
+ @resilience.each do |resilience_type, resilience|
2507
+ next unless resilience_type == RT::Battery
2508
+
2509
+ resilience.name = "Resilience: #{resilience_type}"
2510
+ resilience.annual_units = 'hr'
2511
+ resilience.timeseries_units = 'hr'
2512
+ end
2513
+
2221
2514
  # Peak Fuels
2222
2515
  @peak_fuels = {}
2223
- @peak_fuels[[FT::Elec, PFT::Winter]] = PeakFuel.new(report: 'Peak Electricity Winter Total')
2224
- @peak_fuels[[FT::Elec, PFT::Summer]] = PeakFuel.new(report: 'Peak Electricity Summer Total')
2516
+ @peak_fuels[[FT::Elec, PFT::Winter]] = PeakFuel.new(report: 'Peak Electricity Total')
2517
+ @peak_fuels[[FT::Elec, PFT::Summer]] = PeakFuel.new(report: 'Peak Electricity Total')
2518
+ @peak_fuels[[FT::Elec, PFT::Annual]] = PeakFuel.new(report: 'Peak Electricity Total')
2225
2519
 
2226
2520
  @peak_fuels.each do |key, peak_fuel|
2227
2521
  fuel_type, peak_fuel_type = key
@@ -2233,13 +2527,13 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2233
2527
 
2234
2528
  @loads = {}
2235
2529
  @loads[LT::Heating] = Load.new(ems_variable: 'loads_htg_tot')
2236
- @loads[LT::HeatingHeatPumpBackup] = Load.new(variables: get_object_variables(LT, LT::HeatingHeatPumpBackup))
2530
+ @loads[LT::HeatingHeatPumpBackup] = Load.new(variables: get_object_outputs(LT, LT::HeatingHeatPumpBackup))
2237
2531
  @loads[LT::Cooling] = Load.new(ems_variable: 'loads_clg_tot')
2238
- @loads[LT::HotWaterDelivered] = Load.new(variables: get_object_variables(LT, LT::HotWaterDelivered))
2239
- @loads[LT::HotWaterTankLosses] = Load.new(variables: get_object_variables(LT, LT::HotWaterTankLosses),
2532
+ @loads[LT::HotWaterDelivered] = Load.new(variables: get_object_outputs(LT, LT::HotWaterDelivered))
2533
+ @loads[LT::HotWaterTankLosses] = Load.new(variables: get_object_outputs(LT, LT::HotWaterTankLosses),
2240
2534
  is_negative: true)
2241
- @loads[LT::HotWaterDesuperheater] = Load.new(variables: get_object_variables(LT, LT::HotWaterDesuperheater))
2242
- @loads[LT::HotWaterSolarThermal] = Load.new(variables: get_object_variables(LT, LT::HotWaterSolarThermal),
2535
+ @loads[LT::HotWaterDesuperheater] = Load.new(variables: get_object_outputs(LT, LT::HotWaterDesuperheater))
2536
+ @loads[LT::HotWaterSolarThermal] = Load.new(variables: get_object_outputs(LT, LT::HotWaterSolarThermal),
2243
2537
  is_negative: true)
2244
2538
 
2245
2539
  @loads.each do |load_type, load|
@@ -2325,10 +2619,10 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2325
2619
 
2326
2620
  # Airflows
2327
2621
  @airflows = {}
2328
- @airflows[AFT::Infiltration] = Airflow.new(ems_program: Constants.ObjectNameInfiltration + ' program', ems_variables: [(Constants.ObjectNameInfiltration + ' flow act').gsub(' ', '_')])
2329
- @airflows[AFT::MechanicalVentilation] = Airflow.new(ems_program: Constants.ObjectNameInfiltration + ' program', ems_variables: ['Qfan'])
2330
- @airflows[AFT::NaturalVentilation] = Airflow.new(ems_program: Constants.ObjectNameNaturalVentilation + ' program', ems_variables: [(Constants.ObjectNameNaturalVentilation + ' flow act').gsub(' ', '_')])
2331
- @airflows[AFT::WholeHouseFan] = Airflow.new(ems_program: Constants.ObjectNameNaturalVentilation + ' program', ems_variables: [(Constants.ObjectNameWholeHouseFan + ' flow act').gsub(' ', '_')])
2622
+ @airflows[AFT::Infiltration] = Airflow.new(ems_program: Constants.ObjectNameInfiltration, ems_variable: (Constants.ObjectNameInfiltration + ' flow act').gsub(' ', '_'))
2623
+ @airflows[AFT::MechanicalVentilation] = Airflow.new(ems_program: Constants.ObjectNameInfiltration, ems_variable: 'Qfan')
2624
+ @airflows[AFT::NaturalVentilation] = Airflow.new(ems_program: Constants.ObjectNameNaturalVentilation, ems_variable: (Constants.ObjectNameNaturalVentilation + ' flow act').gsub(' ', '_'))
2625
+ @airflows[AFT::WholeHouseFan] = Airflow.new(ems_program: Constants.ObjectNameNaturalVentilation, ems_variable: (Constants.ObjectNameWholeHouseFan + ' flow act').gsub(' ', '_'))
2332
2626
 
2333
2627
  @airflows.each do |airflow_type, airflow|
2334
2628
  airflow.name = "Airflow: #{airflow_type}"
@@ -2370,7 +2664,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2370
2664
  args[:include_timeseries_fuel_consumptions] = true
2371
2665
  end
2372
2666
  end
2373
- if args[:include_timeseries_total_consumptions]
2667
+ if args[:include_timeseries_total_consumptions] || args[:include_timeseries_resilience]
2374
2668
  args[:include_timeseries_fuel_consumptions] = true
2375
2669
  end
2376
2670
  if args[:include_timeseries_fuel_consumptions]
@@ -2382,41 +2676,25 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2382
2676
  return args
2383
2677
  end
2384
2678
 
2385
- def is_heat_pump_backup(sys_id)
2386
- return false if @hpxml.nil?
2387
-
2388
- # Integrated backup?
2389
- @hpxml.heat_pumps.each do |heat_pump|
2390
- next if sys_id != heat_pump.id
2391
-
2392
- return true
2393
- end
2394
-
2395
- # Separate backup system?
2396
- @hpxml.heating_systems.each do |heating_system|
2397
- next if sys_id != heating_system.id
2398
- next unless heating_system.is_heat_pump_backup_system
2399
-
2400
- return true
2401
- end
2402
-
2403
- return false
2404
- end
2405
-
2406
2679
  def get_hpxml_system_ids
2407
2680
  # Returns a list of HPXML IDs corresponds to HVAC or water heating systems
2408
- return [] if @hpxml.nil?
2681
+ return [] if @hpxml_bldgs.empty?
2409
2682
 
2410
2683
  system_ids = []
2411
- (@hpxml.hvac_systems + @hpxml.water_heating_systems + @hpxml.ventilation_fans).each do |system|
2412
- system_ids << system.id
2684
+ @hpxml_bldgs.each do |hpxml_bldg|
2685
+ (hpxml_bldg.hvac_systems + hpxml_bldg.water_heating_systems + hpxml_bldg.ventilation_fans).each do |system|
2686
+ system_ids << system.id
2687
+ end
2413
2688
  end
2414
2689
  return system_ids
2415
2690
  end
2416
2691
 
2417
- def get_object_output_variables_by_key(model, object, sys_id, class_name)
2418
- # For a given object, returns the output variables to be requested and associates
2419
- # them with the appropriate keys (e.g., [FT::Elec, EUT::Heating]).
2692
+ def get_object_outputs_by_key(model, object, class_name)
2693
+ # For a given object, returns the Output:Variables or Output:Meters to be requested,
2694
+ # and associates them with the appropriate keys (e.g., [FT::Elec, EUT::Heating]).
2695
+
2696
+ object_type = object.additionalProperties.getFeatureAsString('ObjectType')
2697
+ object_type = object_type.get if object_type.is_initialized
2420
2698
 
2421
2699
  to_ft = { EPlus::FuelTypeElectricity => FT::Elec,
2422
2700
  EPlus::FuelTypeNaturalGas => FT::Gas,
@@ -2434,28 +2712,28 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2434
2712
  return { [FT::Elec, EUT::Heating] => ["Heating Coil #{EPlus::FuelTypeElectricity} Energy", "Heating Coil Crankcase Heater #{EPlus::FuelTypeElectricity} Energy", "Heating Coil Defrost #{EPlus::FuelTypeElectricity} Energy"] }
2435
2713
 
2436
2714
  elsif object.to_CoilHeatingElectric.is_initialized
2437
- if not is_heat_pump_backup(sys_id)
2438
- return { [FT::Elec, EUT::Heating] => ["Heating Coil #{EPlus::FuelTypeElectricity} Energy"] }
2439
- else
2715
+ if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized && object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get
2440
2716
  return { [FT::Elec, EUT::HeatingHeatPumpBackup] => ["Heating Coil #{EPlus::FuelTypeElectricity} Energy"] }
2717
+ else
2718
+ return { [FT::Elec, EUT::Heating] => ["Heating Coil #{EPlus::FuelTypeElectricity} Energy"] }
2441
2719
  end
2442
2720
 
2443
2721
  elsif object.to_CoilHeatingGas.is_initialized
2444
2722
  fuel = object.to_CoilHeatingGas.get.fuelType
2445
- if not is_heat_pump_backup(sys_id)
2446
- return { [to_ft[fuel], EUT::Heating] => ["Heating Coil #{fuel} Energy", "Heating Coil Ancillary #{fuel} Energy"] }
2447
- else
2723
+ if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized && object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get
2448
2724
  return { [to_ft[fuel], EUT::HeatingHeatPumpBackup] => ["Heating Coil #{fuel} Energy", "Heating Coil Ancillary #{fuel} Energy"] }
2725
+ else
2726
+ return { [to_ft[fuel], EUT::Heating] => ["Heating Coil #{fuel} Energy", "Heating Coil Ancillary #{fuel} Energy"] }
2449
2727
  end
2450
2728
 
2451
2729
  elsif object.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized
2452
2730
  return { [FT::Elec, EUT::Heating] => ["Heating Coil #{EPlus::FuelTypeElectricity} Energy"] }
2453
2731
 
2454
2732
  elsif object.to_ZoneHVACBaseboardConvectiveElectric.is_initialized
2455
- if not is_heat_pump_backup(sys_id)
2456
- return { [FT::Elec, EUT::Heating] => ["Baseboard #{EPlus::FuelTypeElectricity} Energy"] }
2457
- else
2733
+ if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized && object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get
2458
2734
  return { [FT::Elec, EUT::HeatingHeatPumpBackup] => ["Baseboard #{EPlus::FuelTypeElectricity} Energy"] }
2735
+ else
2736
+ return { [FT::Elec, EUT::Heating] => ["Baseboard #{EPlus::FuelTypeElectricity} Energy"] }
2459
2737
  end
2460
2738
 
2461
2739
  elsif object.to_BoilerHotWater.is_initialized
@@ -2465,14 +2743,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2465
2743
  end
2466
2744
  if not is_combi_boiler # Exclude combi boiler, whose heating & dhw energy is handled separately via EMS
2467
2745
  fuel = object.to_BoilerHotWater.get.fuelType
2468
- if not is_heat_pump_backup(sys_id)
2469
- return { [to_ft[fuel], EUT::Heating] => ["Boiler #{fuel} Energy"] }
2746
+ if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized && object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get
2747
+ return { [to_ft[fuel], EUT::HeatingHeatPumpBackup] => ["Boiler #{fuel} Energy", "Boiler Ancillary #{fuel} Energy"] }
2470
2748
  else
2471
- return { [to_ft[fuel], EUT::HeatingHeatPumpBackup] => ["Boiler #{fuel} Energy"] }
2749
+ return { [to_ft[fuel], EUT::Heating] => ["Boiler #{fuel} Energy", "Boiler Ancillary #{fuel} Energy"] }
2472
2750
  end
2473
2751
  else
2474
2752
  fuel = object.to_BoilerHotWater.get.fuelType
2475
- return { [to_ft[fuel], EUT::HotWater] => ["Boiler #{fuel} Energy"] }
2753
+ return { [to_ft[fuel], EUT::HotWater] => ["Boiler #{fuel} Energy", "Boiler Ancillary #{fuel} Energy"] }
2476
2754
  end
2477
2755
 
2478
2756
  elsif object.to_CoilCoolingDXSingleSpeed.is_initialized || object.to_CoilCoolingDXMultiSpeed.is_initialized
@@ -2507,12 +2785,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2507
2785
  return { [FT::Elec, EUT::HotWater] => ["Cooling Coil Water Heating #{EPlus::FuelTypeElectricity} Energy"] }
2508
2786
 
2509
2787
  elsif object.to_FanSystemModel.is_initialized
2510
- if object.name.to_s.start_with? Constants.ObjectNameWaterHeater
2788
+ if object_type == Constants.ObjectNameWaterHeater
2511
2789
  return { [FT::Elec, EUT::HotWater] => ["Fan #{EPlus::FuelTypeElectricity} Energy"] }
2512
2790
  end
2513
2791
 
2514
2792
  elsif object.to_PumpConstantSpeed.is_initialized
2515
- if object.name.to_s.start_with? Constants.ObjectNameSolarHotWater
2793
+ if object_type == Constants.ObjectNameSolarHotWater
2516
2794
  return { [FT::Elec, EUT::HotWaterSolarThermalPump] => ["Pump #{EPlus::FuelTypeElectricity} Energy"] }
2517
2795
  end
2518
2796
 
@@ -2525,12 +2803,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2525
2803
  return { [to_ft[fuel], EUT::HotWater] => ["Water Heater #{fuel} Energy", "Water Heater Off Cycle Parasitic #{EPlus::FuelTypeElectricity} Energy", "Water Heater On Cycle Parasitic #{EPlus::FuelTypeElectricity} Energy"] }
2526
2804
 
2527
2805
  elsif object.to_ExteriorLights.is_initialized
2528
- return { [FT::Elec, EUT::LightsExterior] => ["Exterior Lights #{EPlus::FuelTypeElectricity} Energy"] }
2806
+ subcategory = object.to_ExteriorLights.get.endUseSubcategory
2807
+ return { [FT::Elec, EUT::LightsExterior] => ["#{subcategory}:ExteriorLights:#{EPlus::FuelTypeElectricity}"] }
2529
2808
 
2530
2809
  elsif object.to_Lights.is_initialized
2531
- end_use = { Constants.ObjectNameInteriorLighting => EUT::LightsInterior,
2532
- Constants.ObjectNameGarageLighting => EUT::LightsGarage }[object.to_Lights.get.endUseSubcategory]
2533
- return { [FT::Elec, end_use] => ["Lights #{EPlus::FuelTypeElectricity} Energy"] }
2810
+ subcategory = object.to_Lights.get.endUseSubcategory
2811
+ end_use = { Constants.ObjectNameLightingInterior => EUT::LightsInterior,
2812
+ Constants.ObjectNameLightingGarage => EUT::LightsGarage }[subcategory]
2813
+ return { [FT::Elec, end_use] => ["#{subcategory}:InteriorLights:#{EPlus::FuelTypeElectricity}"] }
2534
2814
 
2535
2815
  elsif object.to_ElectricLoadCenterInverterPVWatts.is_initialized
2536
2816
  return { [FT::Elec, EUT::PV] => ['Inverter Conversion Loss Decrement Energy'] }
@@ -2544,66 +2824,89 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2544
2824
  [to_ft[fuel], EUT::Generator] => ["Generator #{fuel} HHV Basis Energy"] }
2545
2825
 
2546
2826
  elsif object.to_ElectricLoadCenterStorageLiIonNMCBattery.is_initialized
2547
- # return { [FT::Elec, EUT::Battery] => ['Electric Storage Production Decrement Energy', 'Electric Storage Discharge Energy', 'Electric Storage Thermal Loss Energy'] }
2548
2827
  return { [FT::Elec, EUT::Battery] => ['Electric Storage Production Decrement Energy', 'Electric Storage Discharge Energy'] }
2549
2828
 
2550
2829
  elsif object.to_ElectricEquipment.is_initialized
2551
- end_use = { Constants.ObjectNameHotWaterRecircPump => EUT::HotWaterRecircPump,
2552
- Constants.ObjectNameGSHPSharedPump => 'TempGSHPSharedPump',
2553
- Constants.ObjectNameClothesWasher => EUT::ClothesWasher,
2554
- Constants.ObjectNameClothesDryer => EUT::ClothesDryer,
2555
- Constants.ObjectNameDishwasher => EUT::Dishwasher,
2556
- Constants.ObjectNameRefrigerator => EUT::Refrigerator,
2557
- Constants.ObjectNameFreezer => EUT::Freezer,
2558
- Constants.ObjectNameCookingRange => EUT::RangeOven,
2559
- Constants.ObjectNameCeilingFan => EUT::CeilingFan,
2560
- Constants.ObjectNameWholeHouseFan => EUT::WholeHouseFan,
2561
- Constants.ObjectNameMechanicalVentilation => EUT::MechVent,
2562
- Constants.ObjectNameMiscPlugLoads => EUT::PlugLoads,
2563
- Constants.ObjectNameMiscTelevision => EUT::Television,
2564
- Constants.ObjectNameMiscPoolHeater => EUT::PoolHeater,
2565
- Constants.ObjectNameMiscPoolPump => EUT::PoolPump,
2566
- Constants.ObjectNameMiscHotTubHeater => EUT::HotTubHeater,
2567
- Constants.ObjectNameMiscHotTubPump => EUT::HotTubPump,
2568
- Constants.ObjectNameMiscElectricVehicleCharging => EUT::Vehicle,
2569
- Constants.ObjectNameMiscWellPump => EUT::WellPump }[object.to_ElectricEquipment.get.endUseSubcategory]
2830
+ object = object.to_ElectricEquipment.get
2831
+ subcategory = object.endUseSubcategory
2832
+ end_use = nil
2833
+ { Constants.ObjectNameHotWaterRecircPump => EUT::HotWaterRecircPump,
2834
+ Constants.ObjectNameGSHPSharedPump => 'TempGSHPSharedPump',
2835
+ Constants.ObjectNameClothesWasher => EUT::ClothesWasher,
2836
+ Constants.ObjectNameClothesDryer => EUT::ClothesDryer,
2837
+ Constants.ObjectNameDishwasher => EUT::Dishwasher,
2838
+ Constants.ObjectNameRefrigerator => EUT::Refrigerator,
2839
+ Constants.ObjectNameFreezer => EUT::Freezer,
2840
+ Constants.ObjectNameCookingRange => EUT::RangeOven,
2841
+ Constants.ObjectNameCeilingFan => EUT::CeilingFan,
2842
+ Constants.ObjectNameWholeHouseFan => EUT::WholeHouseFan,
2843
+ Constants.ObjectNameMechanicalVentilation => EUT::MechVent,
2844
+ Constants.ObjectNameMiscPlugLoads => EUT::PlugLoads,
2845
+ Constants.ObjectNameMiscTelevision => EUT::Television,
2846
+ Constants.ObjectNameMiscPoolHeater => EUT::PoolHeater,
2847
+ Constants.ObjectNameMiscPoolPump => EUT::PoolPump,
2848
+ Constants.ObjectNameMiscPermanentSpaHeater => EUT::PermanentSpaHeater,
2849
+ Constants.ObjectNameMiscPermanentSpaPump => EUT::PermanentSpaPump,
2850
+ Constants.ObjectNameMiscElectricVehicleCharging => EUT::Vehicle,
2851
+ Constants.ObjectNameMiscWellPump => EUT::WellPump }.each do |obj_name, eut|
2852
+ next unless subcategory.start_with? obj_name
2853
+ fail 'Unepected error: multiple matches.' unless end_use.nil?
2854
+
2855
+ end_use = eut
2856
+ end
2857
+
2570
2858
  if not end_use.nil?
2571
- return { [FT::Elec, end_use] => ["Electric Equipment #{EPlus::FuelTypeElectricity} Energy"] }
2859
+ # Use Output:Meter instead of Output:Variable because they incorporate thermal zone multipliers
2860
+ if object.space.is_initialized
2861
+ zone_name = object.space.get.thermalZone.get.name.to_s.upcase
2862
+ return { [FT::Elec, end_use] => ["#{subcategory}:InteriorEquipment:#{EPlus::FuelTypeElectricity}:Zone:#{zone_name}"] }
2863
+ else
2864
+ return { [FT::Elec, end_use] => ["#{subcategory}:InteriorEquipment:#{EPlus::FuelTypeElectricity}"] }
2865
+ end
2572
2866
  end
2573
2867
 
2574
2868
  elsif object.to_OtherEquipment.is_initialized
2575
- fuel = object.to_OtherEquipment.get.fuelType
2576
- end_use = { Constants.ObjectNameClothesDryer => EUT::ClothesDryer,
2577
- Constants.ObjectNameCookingRange => EUT::RangeOven,
2578
- Constants.ObjectNameMiscGrill => EUT::Grill,
2579
- Constants.ObjectNameMiscLighting => EUT::Lighting,
2580
- Constants.ObjectNameMiscFireplace => EUT::Fireplace,
2581
- Constants.ObjectNameMiscPoolHeater => EUT::PoolHeater,
2582
- Constants.ObjectNameMiscHotTubHeater => EUT::HotTubHeater,
2583
- Constants.ObjectNameMechanicalVentilationPreheating => EUT::MechVentPreheat,
2584
- Constants.ObjectNameMechanicalVentilationPrecooling => EUT::MechVentPrecool }[object.to_OtherEquipment.get.endUseSubcategory]
2869
+ object = object.to_OtherEquipment.get
2870
+ subcategory = object.endUseSubcategory
2871
+ fuel = object.fuelType
2872
+ end_use = nil
2873
+ { Constants.ObjectNameClothesDryer => EUT::ClothesDryer,
2874
+ Constants.ObjectNameCookingRange => EUT::RangeOven,
2875
+ Constants.ObjectNameMiscGrill => EUT::Grill,
2876
+ Constants.ObjectNameMiscLighting => EUT::Lighting,
2877
+ Constants.ObjectNameMiscFireplace => EUT::Fireplace,
2878
+ Constants.ObjectNameMiscPoolHeater => EUT::PoolHeater,
2879
+ Constants.ObjectNameMiscPermanentSpaHeater => EUT::PermanentSpaHeater,
2880
+ Constants.ObjectNameMechanicalVentilationPreheating => EUT::MechVentPreheat,
2881
+ Constants.ObjectNameMechanicalVentilationPrecooling => EUT::MechVentPrecool,
2882
+ Constants.ObjectNameWaterHeaterAdjustment => EUT::HotWater,
2883
+ Constants.ObjectNameBatteryLossesAdjustment => EUT::Battery }.each do |obj_name, eut|
2884
+ next unless subcategory.start_with? obj_name
2885
+ fail 'Unepected error: multiple matches.' unless end_use.nil?
2886
+
2887
+ end_use = eut
2888
+ end
2889
+
2585
2890
  if not end_use.nil?
2586
- return { [to_ft[fuel], end_use] => ["Other Equipment #{fuel} Energy"] }
2891
+ # Use Output:Meter instead of Output:Variable because they incorporate thermal zone multipliers
2892
+ if object.space.is_initialized
2893
+ zone_name = object.space.get.thermalZone.get.name.to_s.upcase
2894
+ return { [to_ft[fuel], end_use] => ["#{subcategory}:InteriorEquipment:#{fuel}:Zone:#{zone_name}"] }
2895
+ else
2896
+ return { [to_ft[fuel], end_use] => ["#{subcategory}:InteriorEquipment:#{fuel}"] }
2897
+ end
2587
2898
  end
2588
2899
 
2589
2900
  elsif object.to_ZoneHVACDehumidifierDX.is_initialized
2590
2901
  return { [FT::Elec, EUT::Dehumidifier] => ["Zone Dehumidifier #{EPlus::FuelTypeElectricity} Energy"] }
2591
2902
 
2592
2903
  elsif object.to_EnergyManagementSystemOutputVariable.is_initialized
2593
- if object.name.to_s.end_with? Constants.ObjectNameFanPumpDisaggregatePrimaryHeat
2904
+ if object_type == Constants.ObjectNameFanPumpDisaggregatePrimaryHeat
2594
2905
  return { [FT::Elec, EUT::HeatingFanPump] => [object.name.to_s] }
2595
- elsif object.name.to_s.end_with? Constants.ObjectNameFanPumpDisaggregateBackupHeat
2906
+ elsif object_type == Constants.ObjectNameFanPumpDisaggregateBackupHeat
2596
2907
  return { [FT::Elec, EUT::HeatingHeatPumpBackupFanPump] => [object.name.to_s] }
2597
- elsif object.name.to_s.end_with? Constants.ObjectNameFanPumpDisaggregateCool
2908
+ elsif object_type == Constants.ObjectNameFanPumpDisaggregateCool
2598
2909
  return { [FT::Elec, EUT::CoolingFanPump] => [object.name.to_s] }
2599
- elsif object.name.to_s.include? Constants.ObjectNameWaterHeaterAdjustment(nil)
2600
- fuel = object.additionalProperties.getFeatureAsString('FuelType').get
2601
- return { [to_ft[fuel], EUT::HotWater] => [object.name.to_s] }
2602
- elsif object.name.to_s.include? Constants.ObjectNameBatteryLossesAdjustment(nil)
2603
- return { [FT::Elec, EUT::Battery] => [object.name.to_s] }
2604
- elsif object.name.to_s.include? Constants.ObjectNameBoilerPilotLight(nil)
2605
- fuel = object.additionalProperties.getFeatureAsString('FuelType').get
2606
- return { [to_ft[fuel], EUT::Heating] => [object.name.to_s] }
2607
2910
  else
2608
2911
  return { ems: [object.name.to_s] }
2609
2912
  end
@@ -2637,7 +2940,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2637
2940
  if object.additionalProperties.getFeatureAsBoolean('IsCombiBoiler').is_initialized
2638
2941
  is_combi_boiler = object.additionalProperties.getFeatureAsBoolean('IsCombiBoiler').get
2639
2942
  end
2640
- if capacity == 0 && object.name.to_s.include?(Constants.ObjectNameSolarHotWater)
2943
+ if capacity == 0 && object_type == Constants.ObjectNameSolarHotWater
2641
2944
  return { LT::HotWaterSolarThermal => ['Water Heater Use Side Heat Transfer Energy'] }
2642
2945
  elsif capacity > 0 || is_combi_boiler # Active water heater only (e.g., exclude desuperheater and solar thermal storage tanks)
2643
2946
  return { LT::HotWaterTankLosses => ['Water Heater Heat Loss Energy'] }
@@ -2650,27 +2953,36 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2650
2953
  return { LT::HotWaterDesuperheater => ['Water Heater Heating Energy'] }
2651
2954
 
2652
2955
  elsif object.to_CoilHeatingGas.is_initialized || object.to_CoilHeatingElectric.is_initialized
2653
- if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized
2654
- if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get
2655
- return { LT::HeatingHeatPumpBackup => ['Heating Coil Heating Energy'] }
2656
- end
2956
+ if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized && object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get
2957
+ return { LT::HeatingHeatPumpBackup => ['Heating Coil Heating Energy'] }
2657
2958
  end
2658
2959
 
2659
2960
  elsif object.to_ZoneHVACBaseboardConvectiveElectric.is_initialized || object.to_ZoneHVACBaseboardConvectiveWater.is_initialized
2660
- if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized
2661
- if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get
2662
- return { LT::HeatingHeatPumpBackup => ['Baseboard Total Heating Energy'] }
2663
- end
2961
+ if object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').is_initialized && object.additionalProperties.getFeatureAsBoolean('IsHeatPumpBackup').get
2962
+ return { LT::HeatingHeatPumpBackup => ['Baseboard Total Heating Energy'] }
2664
2963
  end
2665
2964
 
2666
2965
  elsif object.to_EnergyManagementSystemOutputVariable.is_initialized
2667
- if object.name.to_s.end_with? Constants.ObjectNameFanPumpDisaggregateBackupHeat
2966
+ if object_type == Constants.ObjectNameFanPumpDisaggregateBackupHeat
2668
2967
  # Fan/pump energy is contributing to the load
2669
2968
  return { LT::HeatingHeatPumpBackup => [object.name.to_s] }
2670
2969
  end
2671
2970
 
2672
2971
  end
2673
2972
 
2973
+ elsif class_name == RT
2974
+
2975
+ # Resilience
2976
+
2977
+ if object.to_ElectricLoadCenterStorageLiIonNMCBattery.is_initialized
2978
+ return { RT::Battery => ['Electric Storage Charge Fraction'] }
2979
+
2980
+ elsif object.to_OtherEquipment.is_initialized
2981
+ if object_type == Constants.ObjectNameBatteryLossesAdjustment
2982
+ return { RT::Battery => ["Other Equipment #{EPlus::FuelTypeElectricity} Energy"] }
2983
+ end
2984
+
2985
+ end
2674
2986
  end
2675
2987
 
2676
2988
  return {}