urbanopt-cli 0.9.3 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (641) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/{nightly_build.yml → nightly_ci_build.yml} +6 -5
  3. data/CHANGELOG.md +11 -2
  4. data/CMakeLists.txt +7 -7
  5. data/Gemfile +6 -5
  6. data/LICENSE.md +18 -15
  7. data/README.md +2 -1
  8. data/Rakefile +2 -37
  9. data/example_files/Gemfile +8 -8
  10. data/example_files/mappers/Baseline.rb +170 -191
  11. data/example_files/mappers/ChilledWaterStorage.rb +8 -30
  12. data/example_files/mappers/ClassProject.rb +2 -27
  13. data/example_files/mappers/CreateBar.rb +2 -28
  14. data/example_files/mappers/EvCharging.rb +2 -27
  15. data/example_files/mappers/FlexibleHotWater.rb +2 -27
  16. data/example_files/mappers/Floorspace.rb +2 -27
  17. data/example_files/mappers/HighEfficiency.rb +2 -27
  18. data/example_files/mappers/HighEfficiencyCreateBar.rb +2 -27
  19. data/example_files/mappers/HighEfficiencyFloorspace.rb +2 -27
  20. data/example_files/mappers/PeakHoursMelsShedding.rb +4 -27
  21. data/example_files/mappers/PeakHoursThermostatAdjust.rb +4 -27
  22. data/example_files/mappers/ThermalStorage.rb +2 -28
  23. data/example_files/measures/BuildResidentialModel/measure.rb +30 -60
  24. data/example_files/measures/BuildResidentialModel/measure.xml +253 -84
  25. data/example_files/measures/BuildResidentialModel/resources/util.rb +45 -45
  26. data/example_files/python_deps/dependencies.json +3 -3
  27. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +1 -1
  28. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +28 -19
  29. data/example_files/resources/hpxml-measures/.gitignore +0 -997
  30. data/example_files/resources/hpxml-measures/.readthedocs.yml +9 -0
  31. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +476 -230
  32. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +244 -75
  33. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +42 -15
  34. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +24 -9
  35. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.rb +11 -33
  36. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml +23 -50
  37. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/README.md +2 -2
  38. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/constants.rb +119 -0
  39. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb +67 -290
  40. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules_config.md +6 -5
  41. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/tests/build_residential_schedule_file_test.rb +78 -349
  42. data/example_files/resources/hpxml-measures/Changelog.md +80 -10
  43. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +212 -144
  44. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +164 -170
  45. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +238 -167
  46. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/battery.rb +1 -1
  47. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +12 -4
  48. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +36 -6
  49. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/unavailable_periods.csv +33 -0
  50. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +1 -0
  51. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +9 -7
  52. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +79 -61
  53. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +387 -124
  54. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +427 -196
  55. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXML.xsd +11515 -2
  56. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/README.md +1 -0
  57. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml +224 -85
  58. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +334 -319
  59. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +572 -838
  60. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +162 -68
  61. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +4 -20
  62. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +12 -10
  63. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +34 -37
  64. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/output.rb +8 -101
  65. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/psychrometrics.rb +31 -40
  66. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/pv.rb +1 -1
  67. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-non-stochastic.csv +8761 -0
  68. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic-10-mins.csv +52561 -52561
  69. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic.csv +8761 -8761
  70. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +384 -155
  71. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/unit_conversions.rb +1 -1
  72. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/util.rb +2 -2
  73. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +2 -2
  74. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +68 -90
  75. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/weather.rb +34 -223
  76. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +1 -1
  77. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlvalidator.rb +16 -4
  78. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +94 -40
  79. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +765 -302
  80. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +119 -69
  81. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +8 -8
  82. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +1 -1
  83. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +51 -11
  84. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +196 -9
  85. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +36 -13
  86. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +3 -3
  87. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +2 -2
  88. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_schedules.rb +571 -61
  89. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +190 -81
  90. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +11 -11
  91. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_weather.rb +188 -50
  92. data/example_files/resources/hpxml-measures/README.md +3 -3
  93. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.rb +659 -815
  94. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.xml +301 -1112
  95. data/example_files/resources/hpxml-measures/ReportSimulationOutput/tests/output_report_test.rb +605 -350
  96. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.rb +18 -14
  97. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.xml +15 -15
  98. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/utility_bills_test.rb +13 -3
  99. data/example_files/resources/hpxml-measures/docs/source/usage_instructions.rst +3 -3
  100. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +894 -596
  101. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +127 -76
  102. data/example_files/resources/hpxml-measures/tasks.rb +185 -2802
  103. data/example_files/resources/hpxml-measures/workflow/hpxml_inputs.json +3401 -0
  104. data/example_files/resources/hpxml-measures/workflow/real_homes/house001.xml +0 -1
  105. data/example_files/resources/hpxml-measures/workflow/real_homes/house002.xml +0 -1
  106. data/example_files/resources/hpxml-measures/workflow/real_homes/house003.xml +0 -1
  107. data/example_files/resources/hpxml-measures/workflow/real_homes/house004.xml +0 -1
  108. data/example_files/resources/hpxml-measures/workflow/real_homes/house005.xml +0 -1
  109. data/example_files/resources/hpxml-measures/workflow/real_homes/house006.xml +1 -3
  110. data/example_files/resources/hpxml-measures/workflow/real_homes/house007.xml +0 -1
  111. data/example_files/resources/hpxml-measures/workflow/real_homes/house008.xml +1 -3
  112. data/example_files/resources/hpxml-measures/workflow/real_homes/house009.xml +0 -1
  113. data/example_files/resources/hpxml-measures/workflow/real_homes/house010.xml +1 -3
  114. data/example_files/resources/hpxml-measures/workflow/real_homes/house011.xml +0 -1
  115. data/example_files/resources/hpxml-measures/workflow/real_homes/house012.xml +0 -1
  116. data/example_files/resources/hpxml-measures/workflow/real_homes/house013.xml +0 -1
  117. data/example_files/resources/hpxml-measures/workflow/real_homes/house014.xml +0 -1
  118. data/example_files/resources/hpxml-measures/workflow/real_homes/house015.xml +0 -1
  119. data/example_files/resources/hpxml-measures/workflow/real_homes/house016.xml +3 -4
  120. data/example_files/resources/hpxml-measures/workflow/real_homes/house017.xml +17 -4
  121. data/example_files/resources/hpxml-measures/workflow/real_homes/house018.xml +2 -3
  122. data/example_files/resources/hpxml-measures/workflow/real_homes/house019.xml +3 -4
  123. data/example_files/resources/hpxml-measures/workflow/real_homes/house020.xml +3 -4
  124. data/example_files/resources/hpxml-measures/workflow/real_homes/house021.xml +4 -5
  125. data/example_files/resources/hpxml-measures/workflow/real_homes/house022.xml +3 -4
  126. data/example_files/resources/hpxml-measures/workflow/real_homes/house023.xml +3 -4
  127. data/example_files/resources/hpxml-measures/workflow/real_homes/house024.xml +3 -4
  128. data/example_files/resources/hpxml-measures/workflow/real_homes/house025.xml +3 -4
  129. data/example_files/resources/hpxml-measures/workflow/real_homes/house026.xml +1 -1
  130. data/example_files/resources/hpxml-measures/workflow/real_homes/house027.xml +1 -1
  131. data/example_files/resources/hpxml-measures/workflow/real_homes/house028.xml +1 -1
  132. data/example_files/resources/hpxml-measures/workflow/real_homes/house029.xml +1 -1
  133. data/example_files/resources/hpxml-measures/workflow/real_homes/house030.xml +0 -1
  134. data/example_files/resources/hpxml-measures/workflow/real_homes/house031.xml +4 -5
  135. data/example_files/resources/hpxml-measures/workflow/real_homes/house032.xml +3 -3
  136. data/example_files/resources/hpxml-measures/workflow/real_homes/house033.xml +3 -3
  137. data/example_files/resources/hpxml-measures/workflow/real_homes/house034.xml +3 -4
  138. data/example_files/resources/hpxml-measures/workflow/real_homes/house035.xml +3 -3
  139. data/example_files/resources/hpxml-measures/workflow/real_homes/house036.xml +3 -4
  140. data/example_files/resources/hpxml-measures/workflow/real_homes/house037.xml +3 -3
  141. data/example_files/resources/hpxml-measures/workflow/real_homes/house038.xml +3 -4
  142. data/example_files/resources/hpxml-measures/workflow/real_homes/house039.xml +3 -3
  143. data/example_files/resources/hpxml-measures/workflow/real_homes/house040.xml +3 -4
  144. data/example_files/resources/hpxml-measures/workflow/real_homes/house041.xml +0 -1
  145. data/example_files/resources/hpxml-measures/workflow/real_homes/house042.xml +0 -1
  146. data/example_files/resources/hpxml-measures/workflow/real_homes/house043.xml +0 -1
  147. data/example_files/resources/hpxml-measures/workflow/real_homes/house044.xml +0 -1
  148. data/example_files/resources/hpxml-measures/workflow/real_homes/house045.xml +0 -1
  149. data/example_files/resources/hpxml-measures/workflow/real_homes/house046.xml +1 -0
  150. data/example_files/resources/hpxml-measures/workflow/real_homes/house047.xml +1 -0
  151. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +12 -8
  152. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +10 -40
  153. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +10 -40
  154. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +10 -40
  155. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +10 -40
  156. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +10 -40
  157. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +10 -40
  158. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +10 -40
  159. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +10 -40
  160. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil-location-miami-fl.xml +10 -40
  161. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +10 -40
  162. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane-location-portland-or.xml +10 -40
  163. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +10 -40
  164. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +10 -40
  165. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +10 -40
  166. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +9 -39
  167. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +9 -39
  168. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +10 -40
  169. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +10 -40
  170. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +10 -40
  171. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery-scheduled.xml +10 -40
  172. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery.xml +10 -40
  173. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-single-family-attached-2stories.xml → base-bldgtype-attached-2stories.xml} +610 -639
  174. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-single-family-attached-atticroof-cathedral.xml → base-bldgtype-attached-atticroof-cathedral.xml} +558 -587
  175. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-attached-infil-compartmentalization-test.xml +611 -0
  176. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-single-family-attached.xml → base-bldgtype-attached.xml} +610 -639
  177. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml +10 -39
  178. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +10 -39
  179. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml +10 -39
  180. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-heated-space.xml +10 -39
  181. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml +10 -39
  182. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-infil-compartmentalization-test.xml +462 -0
  183. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-bldgtype-multifamily-calctype-operational.xml → base-bldgtype-multifamily-residents-1.xml} +453 -480
  184. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +10 -39
  185. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +10 -39
  186. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +10 -39
  187. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +10 -39
  188. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +10 -39
  189. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +10 -39
  190. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +10 -39
  191. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +10 -39
  192. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +10 -39
  193. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +10 -39
  194. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +10 -39
  195. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +10 -39
  196. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +10 -39
  197. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +10 -39
  198. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +10 -39
  199. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +11 -40
  200. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +10 -39
  201. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room-multiple-water-heaters.xml +10 -39
  202. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +10 -39
  203. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-multiple.xml +10 -39
  204. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +10 -39
  205. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +10 -39
  206. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +15 -40
  207. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +10 -39
  208. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +10 -39
  209. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +10 -39
  210. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +10 -40
  211. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +10 -40
  212. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +10 -40
  213. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +10 -40
  214. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +10 -40
  215. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +10 -40
  216. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +10 -40
  217. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +10 -40
  218. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +10 -40
  219. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-detailed-setpoints.xml +10 -40
  220. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +10 -40
  221. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +10 -40
  222. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +10 -40
  223. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +10 -40
  224. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +10 -40
  225. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +10 -40
  226. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +10 -40
  227. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +10 -40
  228. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +10 -40
  229. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +10 -40
  230. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +10 -40
  231. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +10 -40
  232. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +10 -40
  233. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +10 -40
  234. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +10 -40
  235. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +10 -40
  236. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +10 -40
  237. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +10 -40
  238. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +10 -40
  239. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +10 -40
  240. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +10 -40
  241. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +10 -40
  242. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +10 -40
  243. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +10 -40
  244. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-detailed-setpoints.xml +10 -40
  245. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +10 -40
  246. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +10 -40
  247. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef-fhr.xml +10 -40
  248. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +10 -40
  249. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +10 -40
  250. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-detailed-schedules.xml +10 -40
  251. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-operating-mode-heat-pump-only.xml +11 -43
  252. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +10 -40
  253. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +10 -40
  254. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +10 -40
  255. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +10 -40
  256. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +10 -40
  257. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified-detailed-occupancy-stochastic.xml +10 -40
  258. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified.xml +10 -40
  259. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +10 -40
  260. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +10 -40
  261. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-detailed-setpoints.xml +10 -40
  262. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +10 -40
  263. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +10 -40
  264. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +10 -40
  265. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +10 -40
  266. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +10 -40
  267. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +10 -40
  268. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +10 -40
  269. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +10 -40
  270. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +19 -25
  271. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +10 -40
  272. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +10 -40
  273. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +10 -40
  274. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +10 -40
  275. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +10 -40
  276. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-ceilingtypes.xml +10 -40
  277. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-floortypes.xml +10 -40
  278. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +18 -24
  279. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +11 -41
  280. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +11 -41
  281. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +10 -40
  282. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ela.xml +549 -0
  283. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +13 -43
  284. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +10 -40
  285. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-cfm.xml +552 -0
  286. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-orientations.xml +10 -40
  287. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +10 -40
  288. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +17 -47
  289. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-physical-properties.xml +10 -40
  290. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +10 -40
  291. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-storms.xml +10 -40
  292. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +10 -40
  293. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +10 -40
  294. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-thermal-mass.xml +10 -40
  295. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +10 -40
  296. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-natural-ventilation-availability.xml +10 -40
  297. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +10 -40
  298. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-physical-properties.xml +10 -40
  299. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading-seasons.xml +559 -0
  300. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading.xml +10 -40
  301. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-storms.xml +10 -40
  302. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +10 -40
  303. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +19 -25
  304. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +10 -40
  305. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +10 -40
  306. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-wall-insulation.xml +10 -40
  307. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-crawlspace.xml +10 -40
  308. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +10 -40
  309. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +10 -40
  310. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +10 -40
  311. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +10 -40
  312. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +10 -40
  313. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +10 -40
  314. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +10 -40
  315. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +10 -40
  316. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +10 -40
  317. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-autosized-backup.xml +557 -0
  318. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +16 -41
  319. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml → base-hvac-air-to-air-heat-pump-1-speed-heating-capacity-17f.xml} +552 -583
  320. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +16 -41
  321. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-air-to-air-heat-pump-1-speed-backup-lockout-temperature.xml → base-hvac-air-to-air-heat-pump-1-speed-lockout-temperatures.xml} +562 -586
  322. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-seer2-hspf2.xml +16 -41
  323. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +16 -41
  324. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +16 -41
  325. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-hvac-seasons.xml +587 -0
  326. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-switchover-temperature.xml +17 -42
  327. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml +16 -41
  328. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-furnace.xml +16 -41
  329. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +16 -41
  330. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +10 -40
  331. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +10 -40
  332. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +10 -40
  333. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +10 -40
  334. 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 +10 -40
  335. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +10 -40
  336. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-acca.xml +10 -40
  337. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-hers.xml +10 -40
  338. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-maxload.xml +10 -40
  339. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler.xml +10 -40
  340. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-furnace.xml +10 -40
  341. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-acca.xml +10 -40
  342. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-hers.xml +10 -40
  343. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-maxload.xml +10 -40
  344. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-elec-only.xml +10 -40
  345. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-central-ac-1-speed.xml +10 -40
  346. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-only.xml +10 -40
  347. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-1-speed.xml +10 -40
  348. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-2-speed.xml +10 -40
  349. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-var-speed.xml +10 -40
  350. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-plus-air-to-air-heat-pump-heating.xml +10 -40
  351. 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 +11 -41
  352. 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 +11 -41
  353. 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 +11 -41
  354. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted-backup-hardsized.xml +553 -0
  355. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted.xml +11 -41
  356. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-elec-resistance-only.xml +10 -40
  357. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-evap-cooler-furnace-gas.xml +10 -40
  358. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-floor-furnace-propane-only.xml +10 -40
  359. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-elec-only.xml +10 -40
  360. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-2-speed.xml +10 -40
  361. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-var-speed.xml +10 -40
  362. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +10 -40
  363. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-room-ac.xml +10 -40
  364. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +10 -40
  365. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +10 -40
  366. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-acca.xml +10 -40
  367. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-hers.xml +10 -40
  368. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-maxload.xml +10 -40
  369. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +10 -40
  370. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-cooling-only.xml +10 -40
  371. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-heating-only.xml +10 -40
  372. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-acca.xml +10 -40
  373. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-hers.xml +10 -40
  374. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-maxload.xml +10 -40
  375. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-baseboard.xml +519 -0
  376. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-stove.xml +10 -40
  377. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac-with-heating.xml +10 -40
  378. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac.xml +10 -40
  379. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-acca.xml +16 -40
  380. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-hers.xml +16 -40
  381. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-maxload.xml +16 -40
  382. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-only.xml +10 -40
  383. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-heating.xml +10 -40
  384. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-acca.xml +16 -40
  385. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-hers.xml +16 -40
  386. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-maxload.xml +16 -40
  387. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-sizing-controls.xml +566 -0
  388. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-stove-oil-only.xml +10 -40
  389. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-wall-furnace-elec-only.xml +10 -40
  390. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize.xml +10 -40
  391. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +10 -40
  392. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +10 -40
  393. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +10 -40
  394. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only-pilot.xml +513 -0
  395. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +10 -40
  396. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +10 -40
  397. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +10 -40
  398. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +10 -40
  399. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed-seer2.xml +10 -40
  400. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +10 -40
  401. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +10 -40
  402. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +10 -40
  403. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +16 -41
  404. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-crankcase-heater-40w.xml +556 -0
  405. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +10 -40
  406. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-lockout-temperatures.xml +560 -0
  407. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +17 -42
  408. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +17 -42
  409. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +17 -42
  410. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +17 -42
  411. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-fractions.xml +10 -40
  412. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-multipliers.xml +10 -40
  413. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-buried.xml +555 -0
  414. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-effective-rvalue.xml +553 -0
  415. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-cfm50.xml +10 -40
  416. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +10 -40
  417. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +10 -40
  418. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +10 -40
  419. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +10 -40
  420. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +10 -40
  421. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +10 -40
  422. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +10 -40
  423. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only-pilot-light.xml +506 -0
  424. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +10 -40
  425. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +10 -40
  426. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +10 -40
  427. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +10 -40
  428. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +10 -40
  429. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +10 -40
  430. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-detailed-setpoints.xml +10 -40
  431. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-pilot.xml +542 -0
  432. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +10 -40
  433. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +10 -40
  434. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +10 -40
  435. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +10 -40
  436. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +10 -40
  437. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +10 -40
  438. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +10 -40
  439. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +10 -40
  440. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +10 -40
  441. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml +14 -41
  442. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml +14 -41
  443. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-var-speed.xml +14 -41
  444. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-1-speed.xml +10 -40
  445. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-2-speed.xml +10 -40
  446. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-var-speed.xml +10 -40
  447. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-only.xml +10 -40
  448. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-ground-to-air-heat-pump.xml +10 -40
  449. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-air-conditioner-only-ducted.xml +10 -40
  450. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-heat-pump-ducted.xml +14 -41
  451. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +10 -40
  452. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +10 -40
  453. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +16 -41
  454. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +16 -41
  455. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +16 -41
  456. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-baseboard.xml +525 -0
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-furnace.xml +564 -0
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-stove.xml +16 -41
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-heating-capacity-17f.xml +506 -0
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +16 -41
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +10 -40
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +10 -40
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +10 -40
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-electricity.xml +10 -40
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-natural-gas.xml +10 -40
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac.xml +10 -40
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp-heating-capacity-17f.xml +513 -0
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp.xml +16 -40
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +10 -40
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-ceer.xml +10 -40
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-detailed-setpoints.xml +10 -40
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +10 -40
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-heating.xml +10 -40
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-reverse-cycle.xml +16 -40
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-seasons.xml +10 -40
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-schedules.xml +10 -40
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-setbacks.xml +10 -40
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +10 -40
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +10 -40
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +10 -40
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +10 -40
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +10 -40
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +10 -40
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +11 -41
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-holiday.xml +10 -40
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-kwh-per-year.xml +529 -0
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-mixed.xml +537 -0
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none-ceiling-fans.xml +516 -0
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +1 -7
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +10 -40
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +10 -40
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-capetown-zaf.xml +10 -40
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +10 -40
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +10 -40
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +10 -40
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +10 -40
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +10 -40
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +10 -40
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +10 -40
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +10 -40
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +12 -42
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-airflow-fraction-zero.xml +10 -40
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +10 -40
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +10 -40
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-exhaust.xml +10 -40
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-supply.xml +10 -40
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +10 -40
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +10 -40
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +10 -40
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +10 -40
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +10 -40
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +10 -40
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +10 -40
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +14 -44
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +10 -40
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +10 -40
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-additional-properties.xml +10 -38
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-none.xml +10 -40
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-detailed-only.xml +16 -42
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-mixed.xml +16 -42
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv.xml +16 -42
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills.xml +10 -40
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +14 -37
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-emissions.xml +16 -42
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery-scheduled.xml +12 -42
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery.xml +12 -42
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +12 -42
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-ground-conductivity.xml +10 -40
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +10 -38
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +10 -38
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +10 -40
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading-bldgtype-multifamily.xml +509 -0
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +10 -40
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +10 -40
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +10 -41
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +30 -138
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-ah.xml +16 -42
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-garage.xml +24 -26
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-round-trip-efficiency.xml +16 -42
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-scheduled.xml +16 -42
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery.xml +16 -42
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery-scheduled.xml +18 -44
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery.xml +18 -44
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators.xml +18 -44
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +16 -42
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-0-runperiod-1-month.xml +560 -0
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-residents-0.xml +556 -0
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-calctype-operational-misc-loads-large-uncommon.xml → base-residents-1-misc-loads-large-uncommon.xml} +616 -644
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-calctype-operational-misc-loads-large-uncommon2.xml → base-residents-1-misc-loads-large-uncommon2.xml} +616 -644
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-calctype-operational.xml → base-residents-1.xml} +547 -575
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-calctype-operational-misc-defaults.xml → base-residents-5.xml} +515 -539
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-all-10-mins.xml +10 -40
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-10-mins.xml +10 -40
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-power-outage.xml +565 -0
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-schedules-detailed-occupancy-smooth.xml → base-schedules-detailed-occupancy-stochastic-vacancy-year-round.xml} +563 -583
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-vacancy.xml +21 -41
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic.xml +10 -40
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-schedules.xml +10 -40
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-setbacks.xml +10 -40
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints.xml +10 -40
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-power-outage-natvent-available.xml +565 -0
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-power-outage-natvent-unavailable.xml +565 -0
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-power-outage.xml +620 -0
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-vacancy-year-round.xml +619 -0
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple-vacancy.xml +619 -0
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple.xml +10 -38
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +10 -40
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +10 -40
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +10 -40
  570. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +10 -40
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-temperature-capacitance-multiplier.xml +10 -40
  572. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-10-mins.xml +10 -40
  573. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-60-mins.xml +10 -40
  574. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +10 -40
  575. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-30-mins.xml +10 -40
  576. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +10 -37
  577. data/example_files/resources/hpxml-measures/workflow/template-build-and-run-hpxml-with-stochastic-occupancy.osw +16 -4
  578. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy-subset.osw +16 -3
  579. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy.osw +16 -3
  580. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml.osw +16 -2
  581. data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Long_Residence.xml +386 -0
  582. data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Vatilo_Residence.xml +381 -0
  583. data/example_files/resources/hpxml-measures/workflow/tests/ACCA_Examples/Victor_Residence.xml +370 -0
  584. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +2 -2
  585. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +2 -5
  586. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +2 -5
  587. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +2 -5
  588. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +2 -5
  589. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +2 -5
  590. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +2 -5
  591. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +2 -5
  592. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +2 -5
  593. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +2 -5
  594. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +2 -5
  595. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +2 -5
  596. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +2 -5
  597. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +2 -5
  598. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +2 -5
  599. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +2 -5
  600. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +2 -12
  601. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +2 -12
  602. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +2 -5
  603. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +2 -5
  604. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +2 -5
  605. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +2 -5
  606. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +2 -5
  607. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +2 -5
  608. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +6 -9
  609. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +6 -9
  610. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +475 -444
  611. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_bills.csv +475 -444
  612. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +177 -112
  613. data/example_files/resources/meta_measure.rb +2 -27
  614. data/example_files/xml_building/17/README.md +3 -3
  615. data/lib/uo_cli/version.rb +3 -38
  616. data/lib/uo_cli.rb +3 -38
  617. data/uo_cli.gemspec +6 -7
  618. metadata +70 -51
  619. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules_config.json +0 -388
  620. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLBaseElements.xsd +0 -6136
  621. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLDataTypes.xsd +0 -4846
  622. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-smooth.csv +0 -8761
  623. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/occupancy-stochastic-vacancy.csv +0 -8761
  624. data/example_files/resources/hpxml-measures/weather/USA_AZ_Phoenix-Sky.Harbor.Intl.AP.722780_TMY3-cache.csv +0 -35
  625. data/example_files/resources/hpxml-measures/weather/USA_CO_Colorado.Springs-Peterson.Field.724660_TMY3-cache.csv +0 -35
  626. data/example_files/resources/hpxml-measures/weather/USA_CO_Denver.Intl.AP.725650_TMY3-cache.csv +0 -35
  627. data/example_files/resources/hpxml-measures/weather/USA_DE_Wilmington-New.Castle.County.AP.724089_TMY3-cache.csv +0 -35
  628. data/example_files/resources/hpxml-measures/weather/USA_FL_Miami.Intl.AP.722020_TMY3-cache.csv +0 -35
  629. data/example_files/resources/hpxml-measures/weather/USA_HI_Honolulu.Intl.AP.911820_TMY3-cache.csv +0 -35
  630. data/example_files/resources/hpxml-measures/weather/USA_MD_Baltimore-Washington.Intl.AP.724060_TMY3-cache.csv +0 -35
  631. data/example_files/resources/hpxml-measures/weather/USA_MN_Duluth.Intl.AP.727450_TMY3-cache.csv +0 -35
  632. data/example_files/resources/hpxml-measures/weather/USA_MT_Helena.Rgnl.AP.727720_TMY3-cache.csv +0 -35
  633. data/example_files/resources/hpxml-measures/weather/USA_NC_Charlotte-Douglas.Intl.AP.723140_TMY3-cache.csv +0 -35
  634. data/example_files/resources/hpxml-measures/weather/USA_NJ_Cape.May.County.AP.745966_TMY3-cache.csv +0 -35
  635. data/example_files/resources/hpxml-measures/weather/USA_NV_Las.Vegas-McCarran.Intl.AP.723860_TMY3-cache.csv +0 -35
  636. data/example_files/resources/hpxml-measures/weather/USA_OR_Portland.Intl.AP.726980_TMY3-cache.csv +0 -35
  637. data/example_files/resources/hpxml-measures/weather/USA_TX_Dallas-Fort.Worth.Intl.AP.722590_TMY3-cache.csv +0 -35
  638. data/example_files/resources/hpxml-measures/weather/US_CO_Boulder_AMY_2012-cache.csv +0 -35
  639. data/example_files/resources/hpxml-measures/weather/ZAF_Cape.Town.688160_IWEC-cache.csv +0 -35
  640. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +0 -2508
  641. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +0 -2508
@@ -43,6 +43,90 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
43
43
  arg.setDefaultValue('csv')
44
44
  args << arg
45
45
 
46
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_total_consumptions', false)
47
+ arg.setDisplayName('Generate Annual Output: Total Consumptions')
48
+ arg.setDescription('Generates annual energy consumptions for the total building.')
49
+ arg.setDefaultValue(true)
50
+ args << arg
51
+
52
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_fuel_consumptions', false)
53
+ arg.setDisplayName('Generate Annual Output: Fuel Consumptions')
54
+ arg.setDescription('Generates annual energy consumptions for each fuel type.')
55
+ arg.setDefaultValue(true)
56
+ args << arg
57
+
58
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_end_use_consumptions', false)
59
+ arg.setDisplayName('Generate Annual Output: End Use Consumptions')
60
+ arg.setDescription('Generates annual energy consumptions for each end use.')
61
+ arg.setDefaultValue(true)
62
+ args << arg
63
+
64
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_system_use_consumptions', false)
65
+ arg.setDisplayName('Generate Annual Output: System Use Consumptions')
66
+ arg.setDescription('Generates annual energy consumptions for each end use of each HVAC and water heating system.')
67
+ arg.setDefaultValue(true)
68
+ args << arg
69
+
70
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_emissions', false)
71
+ arg.setDisplayName('Generate Annual Output: Emissions')
72
+ arg.setDescription('Generates annual emissions. Requires the appropriate HPXML inputs to be specified.')
73
+ arg.setDefaultValue(true)
74
+ args << arg
75
+
76
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_emission_fuels', false)
77
+ arg.setDisplayName('Generate Annual Output: Emission Fuel Uses')
78
+ arg.setDescription('Generates annual emissions for each fuel type. Requires the appropriate HPXML inputs to be specified.')
79
+ arg.setDefaultValue(true)
80
+ args << arg
81
+
82
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_emission_end_uses', false)
83
+ arg.setDisplayName('Generate Annual Output: Emission End Uses')
84
+ arg.setDescription('Generates annual emissions for each end use. Requires the appropriate HPXML inputs to be specified.')
85
+ arg.setDefaultValue(true)
86
+ args << arg
87
+
88
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_total_loads', false)
89
+ arg.setDisplayName('Generate Annual Output: Total Loads')
90
+ arg.setDescription('Generates annual heating, cooling, and hot water loads.')
91
+ arg.setDefaultValue(true)
92
+ args << arg
93
+
94
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_unmet_hours', false)
95
+ arg.setDisplayName('Generate Annual Output: Unmet Hours')
96
+ arg.setDescription('Generates annual unmet hours for heating and cooling.')
97
+ arg.setDefaultValue(true)
98
+ args << arg
99
+
100
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_peak_fuels', false)
101
+ arg.setDisplayName('Generate Annual Output: Peak Fuels')
102
+ arg.setDescription('Generates annual electricity peaks for summer/winter.')
103
+ arg.setDefaultValue(true)
104
+ args << arg
105
+
106
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_peak_loads', false)
107
+ arg.setDisplayName('Generate Annual Output: Peak Loads')
108
+ arg.setDescription('Generates annual peak loads for heating/cooling.')
109
+ arg.setDefaultValue(true)
110
+ args << arg
111
+
112
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_component_loads', false)
113
+ arg.setDisplayName('Generate Annual Output: Component Loads')
114
+ arg.setDescription('Generates annual heating and cooling loads disaggregated by component type.')
115
+ arg.setDefaultValue(true)
116
+ args << arg
117
+
118
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_hot_water_uses', false)
119
+ arg.setDisplayName('Generate Annual Output: Hot Water Uses')
120
+ arg.setDescription('Generates annual hot water usages for each end use.')
121
+ arg.setDefaultValue(true)
122
+ args << arg
123
+
124
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_annual_hvac_summary', false)
125
+ arg.setDisplayName('Generate Annual Output: HVAC Summary')
126
+ arg.setDescription('Generates HVAC capacities, design temperatures, and design loads.')
127
+ arg.setDefaultValue(true)
128
+ args << arg
129
+
46
130
  timeseries_frequency_chs = OpenStudio::StringVector.new
47
131
  timeseries_frequency_chs << 'none'
48
132
  timeseries_frequency_chs << 'timestep'
@@ -57,7 +141,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
57
141
 
58
142
  arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_total_consumptions', false)
59
143
  arg.setDisplayName('Generate Timeseries Output: Total Consumptions')
60
- arg.setDescription('Generates timeseries energy consumptions for building total.')
144
+ arg.setDescription('Generates timeseries energy consumptions for the total building.')
61
145
  arg.setDefaultValue(false)
62
146
  args << arg
63
147
 
@@ -73,6 +157,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
73
157
  arg.setDefaultValue(false)
74
158
  args << arg
75
159
 
160
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_system_use_consumptions', false)
161
+ arg.setDisplayName('Generate Timeseries Output: System Use Consumptions')
162
+ arg.setDescription('Generates timeseries energy consumptions for each end use of each HVAC and water heating system.')
163
+ arg.setDefaultValue(false)
164
+ args << arg
165
+
76
166
  arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_emissions', false)
77
167
  arg.setDisplayName('Generate Timeseries Output: Emissions')
78
168
  arg.setDescription('Generates timeseries emissions. Requires the appropriate HPXML inputs to be specified.')
@@ -80,7 +170,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
80
170
  args << arg
81
171
 
82
172
  arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_emission_fuels', false)
83
- arg.setDisplayName('Generate Timeseries Output: Emissions')
173
+ arg.setDisplayName('Generate Timeseries Output: Emission Fuel Uses')
84
174
  arg.setDescription('Generates timeseries emissions for each fuel type. Requires the appropriate HPXML inputs to be specified.')
85
175
  arg.setDefaultValue(false)
86
176
  args << arg
@@ -99,7 +189,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
99
189
 
100
190
  arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_total_loads', false)
101
191
  arg.setDisplayName('Generate Timeseries Output: Total Loads')
102
- arg.setDescription('Generates timeseries total heating, cooling, and hot water loads.')
192
+ arg.setDescription('Generates timeseries heating, cooling, and hot water loads.')
103
193
  arg.setDefaultValue(false)
104
194
  args << arg
105
195
 
@@ -142,6 +232,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
142
232
  arg.setDefaultValue('start')
143
233
  args << arg
144
234
 
235
+ arg = OpenStudio::Measure::OSArgument::makeIntegerArgument('timeseries_num_decimal_places', false)
236
+ arg.setDisplayName('Generate Timeseries Output: Number of Decimal Places')
237
+ arg.setDescription('Allows overriding the default number of decimal places for timeseries output. Does not apply if output format is msgpack, where no rounding is performed because there is no file size penalty to storing full precision.')
238
+ args << arg
239
+
145
240
  arg = OpenStudio::Measure::OSArgument::makeBoolArgument('add_timeseries_dst_column', false)
146
241
  arg.setDisplayName('Generate Timeseries Output: Add TimeDST Column')
147
242
  arg.setDescription('Optionally add, in addition to the default local standard Time column, a local clock TimeDST column. Requires that daylight saving time is enabled.')
@@ -159,11 +254,6 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
159
254
  arg.setDescription('Optionally generates timeseries EnergyPlus output variables. If multiple output variables are desired, use a comma-separated list. Do not include key values; by default all key values will be requested. Example: "Zone People Occupant Count, Zone People Total Heating Energy"')
160
255
  args << arg
161
256
 
162
- arg = OpenStudio::Measure::OSArgument::makeBoolArgument('generate_eri_outputs', false)
163
- arg.setDisplayName('Generate ERI Outputs')
164
- arg.setDescription('Optionally generate additional outputs needed for Energy Rating Index (ERI) calculations.')
165
- args << arg
166
-
167
257
  arg = OpenStudio::Measure::OSArgument::makeStringArgument('annual_output_file_name', false)
168
258
  arg.setDisplayName('Annual Output File Name')
169
259
  arg.setDescription("If not provided, defaults to 'results_annual.csv' (or 'results_annual.json' or 'results_annual.msgpack').")
@@ -177,35 +267,28 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
177
267
  return args
178
268
  end
179
269
 
180
- # define the outputs that the measure will create
181
- def outputs
182
- outs = OpenStudio::Measure::OSOutputVector.new
183
-
184
- setup_outputs(true)
185
-
186
- all_outputs = []
187
- all_outputs << @totals
188
- all_outputs << @fuels
189
- all_outputs << @end_uses
190
- all_outputs << @loads
191
- all_outputs << @unmet_hours
192
- all_outputs << @peak_fuels
193
- all_outputs << @peak_loads
194
- all_outputs << @component_loads
195
- all_outputs << @hot_water_uses
196
-
197
- output_names = []
198
- all_outputs.each do |outputs|
199
- outputs.values.each do |obj|
200
- output_names << get_runner_output_name(obj.name, obj.annual_units)
270
+ def get_arguments(runner, arguments, user_arguments)
271
+ args = get_argument_values(runner, arguments, user_arguments)
272
+ args.each do |k, val|
273
+ if val.respond_to?(:is_initialized) && val.is_initialized
274
+ args[k] = val.get
275
+ elsif k.start_with?('include_annual')
276
+ args[k] = true # default if not provided
277
+ elsif k.start_with?('include_timeseries')
278
+ args[k] = false # default if not provided
279
+ else
280
+ args[k] = nil # default if not provided
201
281
  end
202
282
  end
283
+ if args[:timeseries_frequency] == 'none'
284
+ # Override all timeseries arguments
285
+ args.each do |k, _val|
286
+ next unless k.start_with?('include_timeseries')
203
287
 
204
- output_names.each do |output_name|
205
- outs << OpenStudio::Measure::OSOutput.makeDoubleOutput(output_name)
288
+ args[k] = false
289
+ end
206
290
  end
207
-
208
- return outs
291
+ return args
209
292
  end
210
293
 
211
294
  # return a vector of IdfObject's to request EnergyPlus objects needed by the run method
@@ -238,56 +321,10 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
238
321
  has_heating = @model.getBuilding.additionalProperties.getFeatureAsBoolean('has_heating').get
239
322
  has_cooling = @model.getBuilding.additionalProperties.getFeatureAsBoolean('has_cooling').get
240
323
 
241
- timeseries_frequency = runner.getStringArgumentValue('timeseries_frequency', user_arguments)
242
- if timeseries_frequency != 'none'
243
- include_timeseries_total_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_total_consumptions', user_arguments)
244
- include_timeseries_fuel_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_fuel_consumptions', user_arguments)
245
- include_timeseries_end_use_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_end_use_consumptions', user_arguments)
246
- include_timeseries_emissions = runner.getOptionalBoolArgumentValue('include_timeseries_emissions', user_arguments)
247
- include_timeseries_emission_fuels = runner.getOptionalBoolArgumentValue('include_timeseries_emission_fuels', user_arguments)
248
- include_timeseries_emission_end_uses = runner.getOptionalBoolArgumentValue('include_timeseries_emission_end_uses', user_arguments)
249
- include_timeseries_hot_water_uses = runner.getOptionalBoolArgumentValue('include_timeseries_hot_water_uses', user_arguments)
250
- include_timeseries_total_loads = runner.getOptionalBoolArgumentValue('include_timeseries_total_loads', user_arguments)
251
- include_timeseries_component_loads = runner.getOptionalBoolArgumentValue('include_timeseries_component_loads', user_arguments)
252
- include_timeseries_unmet_hours = runner.getOptionalBoolArgumentValue('include_timeseries_unmet_hours', user_arguments)
253
- include_timeseries_zone_temperatures = runner.getOptionalBoolArgumentValue('include_timeseries_zone_temperatures', user_arguments)
254
- include_timeseries_airflows = runner.getOptionalBoolArgumentValue('include_timeseries_airflows', user_arguments)
255
- include_timeseries_weather = runner.getOptionalBoolArgumentValue('include_timeseries_weather', user_arguments)
256
- user_output_variables = runner.getOptionalStringArgumentValue('user_output_variables', user_arguments)
257
-
258
- include_timeseries_total_consumptions = include_timeseries_total_consumptions.is_initialized ? include_timeseries_total_consumptions.get : false
259
- include_timeseries_fuel_consumptions = include_timeseries_fuel_consumptions.is_initialized ? include_timeseries_fuel_consumptions.get : false
260
- include_timeseries_end_use_consumptions = include_timeseries_end_use_consumptions.is_initialized ? include_timeseries_end_use_consumptions.get : false
261
- include_timeseries_emissions = include_timeseries_emissions.is_initialized ? include_timeseries_emissions.get : false
262
- include_timeseries_emission_fuels = include_timeseries_emission_fuels.is_initialized ? include_timeseries_emission_fuels.get : false
263
- include_timeseries_emission_end_uses = include_timeseries_emission_end_uses.is_initialized ? include_timeseries_emission_end_uses.get : false
264
- include_timeseries_hot_water_uses = include_timeseries_hot_water_uses.is_initialized ? include_timeseries_hot_water_uses.get : false
265
- include_timeseries_total_loads = include_timeseries_total_loads.is_initialized ? include_timeseries_total_loads.get : false
266
- include_timeseries_component_loads = include_timeseries_component_loads.is_initialized ? include_timeseries_component_loads.get : false
267
- include_timeseries_unmet_hours = include_timeseries_unmet_hours.is_initialized ? include_timeseries_unmet_hours.get : false
268
- include_timeseries_zone_temperatures = include_timeseries_zone_temperatures.is_initialized ? include_timeseries_zone_temperatures.get : false
269
- include_timeseries_airflows = include_timeseries_airflows.is_initialized ? include_timeseries_airflows.get : false
270
- include_timeseries_weather = include_timeseries_weather.is_initialized ? include_timeseries_weather.get : false
271
- user_output_variables = user_output_variables.is_initialized ? user_output_variables.get : nil
272
- end
273
-
274
- setup_outputs(false, user_output_variables)
324
+ args = get_arguments(runner, arguments(model), user_arguments)
275
325
 
276
- # To calculate timeseries emissions or timeseries fuel consumption, we also need to select timeseries
277
- # end use consumption because EnergyPlus results may be post-processed due to HVAC DSE.
278
- # TODO: This could be removed if we could account for DSE inside EnergyPlus.
279
- if not @emissions.empty?
280
- include_hourly_electric_end_use_consumptions = true # Need hourly electricity values for Cambium
281
- if include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
282
- include_timeseries_fuel_consumptions = true
283
- end
284
- end
285
- if include_timeseries_total_consumptions
286
- include_timeseries_fuel_consumptions = true
287
- end
288
- if include_timeseries_fuel_consumptions
289
- include_timeseries_end_use_consumptions = true
290
- end
326
+ setup_outputs(false, args[:user_output_variables])
327
+ args = setup_timeseries_includes(@emissions, args)
291
328
 
292
329
  has_electricity_production = false
293
330
  if @end_uses.select { |_key, end_use| end_use.is_negative && end_use.variables.size > 0 }.size > 0
@@ -303,8 +340,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
303
340
  @fuels.each do |_fuel_type, fuel|
304
341
  fuel.meters.each do |meter|
305
342
  result << OpenStudio::IdfObject.load("Output:Meter,#{meter},runperiod;").get
306
- if include_timeseries_fuel_consumptions
307
- result << OpenStudio::IdfObject.load("Output:Meter,#{meter},#{timeseries_frequency};").get
343
+ if args[:include_timeseries_fuel_consumptions]
344
+ result << OpenStudio::IdfObject.load("Output:Meter,#{meter},#{args[:timeseries_frequency]};").get
308
345
  end
309
346
  end
310
347
  end
@@ -313,25 +350,24 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
313
350
  end
314
351
  if has_electricity_storage
315
352
  result << OpenStudio::IdfObject.load('Output:Meter,ElectricStorage:ElectricityProduced,runperiod;').get # Used for error checking
316
- if include_timeseries_fuel_consumptions
317
- result << OpenStudio::IdfObject.load("Output:Meter,ElectricStorage:ElectricityProduced,#{timeseries_frequency};").get
353
+ if args[:include_timeseries_fuel_consumptions]
354
+ result << OpenStudio::IdfObject.load("Output:Meter,ElectricStorage:ElectricityProduced,#{args[:timeseries_frequency]};").get
318
355
  end
319
356
  end
320
357
 
321
358
  # End Use/Hot Water Use/Ideal Load outputs
322
- { @end_uses => include_timeseries_end_use_consumptions,
323
- @hot_water_uses => include_timeseries_hot_water_uses,
324
- @ideal_system_loads => false }.each do |uses, include_timeseries|
359
+ { @end_uses => args[:include_timeseries_end_use_consumptions],
360
+ @hot_water_uses => args[:include_timeseries_hot_water_uses] }.each do |uses, include_ts|
325
361
  uses.each do |key, use|
326
362
  use.variables.each do |_sys_id, varkey, var|
327
363
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},runperiod;").get
328
- if include_timeseries
329
- result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},#{timeseries_frequency};").get
364
+ if include_ts
365
+ result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},#{args[:timeseries_frequency]};").get
330
366
  end
331
367
  next unless use.is_a?(EndUse)
332
368
 
333
369
  fuel_type, _end_use = key
334
- if fuel_type == FT::Elec && include_hourly_electric_end_use_consumptions
370
+ if fuel_type == FT::Elec && args[:include_hourly_electric_end_use_consumptions]
335
371
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},hourly;").get
336
372
  end
337
373
  end
@@ -340,9 +376,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
340
376
 
341
377
  # Peak Fuel outputs (annual only)
342
378
  @peak_fuels.values.each do |peak_fuel|
343
- peak_fuel.meters.each do |meter|
344
- result << OpenStudio::IdfObject.load("Output:Table:Monthly,#{peak_fuel.report},2,#{meter},HoursPositive,Electricity:Facility,MaximumDuringHoursShown;").get
345
- end
379
+ result << OpenStudio::IdfObject.load("Output:Table:Monthly,#{peak_fuel.report},2,Electricity:Facility,Maximum;").get
346
380
  end
347
381
 
348
382
  # Peak Load outputs (annual only)
@@ -355,9 +389,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
355
389
  @unmet_hours.each do |_key, unmet_hour|
356
390
  result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{unmet_hour.ems_variable}_annual_outvar,#{unmet_hour.ems_variable},Summed,ZoneTimestep,#{unmet_hours_program.name},hr;").get
357
391
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{unmet_hour.ems_variable}_annual_outvar,runperiod;").get
358
- if include_timeseries_unmet_hours
392
+ if args[:include_timeseries_unmet_hours]
359
393
  result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{unmet_hour.ems_variable}_timeseries_outvar,#{unmet_hour.ems_variable},Summed,ZoneTimestep,#{unmet_hours_program.name},hr;").get
360
- result << OpenStudio::IdfObject.load("Output:Variable,*,#{unmet_hour.ems_variable}_timeseries_outvar,#{timeseries_frequency};").get
394
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{unmet_hour.ems_variable}_timeseries_outvar,#{args[:timeseries_frequency]};").get
361
395
  end
362
396
  end
363
397
 
@@ -367,9 +401,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
367
401
 
368
402
  result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{comp_load.ems_variable}_annual_outvar,#{comp_load.ems_variable},Summed,ZoneTimestep,#{comp_loads_program.name},J;").get
369
403
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{comp_load.ems_variable}_annual_outvar,runperiod;").get
370
- if include_timeseries_component_loads
404
+ if args[:include_timeseries_component_loads]
371
405
  result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{comp_load.ems_variable}_timeseries_outvar,#{comp_load.ems_variable},Summed,ZoneTimestep,#{comp_loads_program.name},J;").get
372
- result << OpenStudio::IdfObject.load("Output:Variable,*,#{comp_load.ems_variable}_timeseries_outvar,#{timeseries_frequency};").get
406
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{comp_load.ems_variable}_timeseries_outvar,#{args[:timeseries_frequency]};").get
373
407
  end
374
408
  end
375
409
 
@@ -378,22 +412,22 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
378
412
  if not load.ems_variable.nil?
379
413
  result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{load.ems_variable}_annual_outvar,#{load.ems_variable},Summed,ZoneTimestep,#{total_loads_program.name},J;").get
380
414
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{load.ems_variable}_annual_outvar,runperiod;").get
381
- if include_timeseries_total_loads
415
+ if args[:include_timeseries_total_loads]
382
416
  result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{load.ems_variable}_timeseries_outvar,#{load.ems_variable},Summed,ZoneTimestep,#{total_loads_program.name},J;").get
383
- result << OpenStudio::IdfObject.load("Output:Variable,*,#{load.ems_variable}_timeseries_outvar,#{timeseries_frequency};").get
417
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{load.ems_variable}_timeseries_outvar,#{args[:timeseries_frequency]};").get
384
418
  end
385
419
  end
386
420
  load.variables.each do |_sys_id, varkey, var|
387
421
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},runperiod;").get
388
- if include_timeseries_total_loads
389
- result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},#{timeseries_frequency};").get
422
+ if args[:include_timeseries_total_loads]
423
+ result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},#{args[:timeseries_frequency]};").get
390
424
  end
391
425
  end
392
426
  end
393
427
 
394
428
  # Temperature outputs (timeseries only)
395
- if include_timeseries_zone_temperatures
396
- result << OpenStudio::IdfObject.load("Output:Variable,*,Zone Mean Air Temperature,#{timeseries_frequency};").get
429
+ if args[:include_timeseries_zone_temperatures]
430
+ result << OpenStudio::IdfObject.load("Output:Variable,*,Zone Mean Air Temperature,#{args[:timeseries_frequency]};").get
397
431
  # For reporting temperature-scheduled spaces timeseries temperatures.
398
432
  keys = [HPXML::LocationOtherHeatedSpace,
399
433
  HPXML::LocationOtherMultifamilyBufferSpace,
@@ -404,46 +438,38 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
404
438
  keys.each do |key|
405
439
  next if @model.getScheduleConstants.select { |o| o.name.to_s == key }.size == 0
406
440
 
407
- result << OpenStudio::IdfObject.load("Output:Variable,#{key},Schedule Value,#{timeseries_frequency};").get
441
+ result << OpenStudio::IdfObject.load("Output:Variable,#{key},Schedule Value,#{args[:timeseries_frequency]};").get
408
442
  end
409
443
  # Also report thermostat setpoints
410
444
  if has_heating
411
- result << OpenStudio::IdfObject.load("Output:Variable,#{HPXML::LocationLivingSpace.upcase},Zone Thermostat Heating Setpoint Temperature,#{timeseries_frequency};").get
445
+ result << OpenStudio::IdfObject.load("Output:Variable,#{HPXML::LocationLivingSpace.upcase},Zone Thermostat Heating Setpoint Temperature,#{args[:timeseries_frequency]};").get
412
446
  end
413
447
  if has_cooling
414
- result << OpenStudio::IdfObject.load("Output:Variable,#{HPXML::LocationLivingSpace.upcase},Zone Thermostat Cooling Setpoint Temperature,#{timeseries_frequency};").get
448
+ result << OpenStudio::IdfObject.load("Output:Variable,#{HPXML::LocationLivingSpace.upcase},Zone Thermostat Cooling Setpoint Temperature,#{args[:timeseries_frequency]};").get
415
449
  end
416
450
  end
417
451
 
418
452
  # Airflow outputs (timeseries only)
419
- if include_timeseries_airflows
453
+ if args[:include_timeseries_airflows]
420
454
  @airflows.values.each do |airflow|
421
455
  ems_program = @model.getModelObjectByName(airflow.ems_program.gsub(' ', '_')).get.to_EnergyManagementSystemProgram.get
422
456
  airflow.ems_variables.each do |ems_variable|
423
457
  result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{ems_variable}_timeseries_outvar,#{ems_variable},Averaged,ZoneTimestep,#{ems_program.name},m^3/s;").get
424
- result << OpenStudio::IdfObject.load("Output:Variable,*,#{ems_variable}_timeseries_outvar,#{timeseries_frequency};").get
458
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{ems_variable}_timeseries_outvar,#{args[:timeseries_frequency]};").get
425
459
  end
426
460
  end
427
461
  end
428
462
 
429
463
  # Weather outputs (timeseries only)
430
- if include_timeseries_weather
464
+ if args[:include_timeseries_weather]
431
465
  @weather.values.each do |weather_data|
432
- result << OpenStudio::IdfObject.load("Output:Variable,*,#{weather_data.variable},#{timeseries_frequency};").get
466
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{weather_data.variable},#{args[:timeseries_frequency]};").get
433
467
  end
434
468
  end
435
469
 
436
470
  # Optional output variables (timeseries only)
437
471
  @output_variables_requests.each do |output_variable_name, _output_variable|
438
- result << OpenStudio::IdfObject.load("Output:Variable,*,#{output_variable_name},#{timeseries_frequency};").get
439
- end
440
-
441
- # Dual-fuel heat pump loads
442
- if not @object_variables_by_key[[LT, LT::Heating]].nil?
443
- @object_variables_by_key[[LT, LT::Heating]].each do |vals|
444
- _sys_id, key, var = vals
445
- result << OpenStudio::IdfObject.load("Output:Variable,#{key},#{var},runperiod;").get
446
- end
472
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{output_variable_name},#{args[:timeseries_frequency]};").get
447
473
  end
448
474
 
449
475
  return result.uniq
@@ -465,59 +491,22 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
465
491
  return false
466
492
  end
467
493
 
468
- output_format = runner.getStringArgumentValue('output_format', user_arguments)
469
- if output_format == 'csv_dview'
470
- output_format = 'csv'
471
- use_dview_format = true
472
- end
473
- timeseries_frequency = runner.getStringArgumentValue('timeseries_frequency', user_arguments)
474
- if timeseries_frequency != 'none'
475
- include_timeseries_total_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_total_consumptions', user_arguments)
476
- include_timeseries_fuel_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_fuel_consumptions', user_arguments)
477
- include_timeseries_end_use_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_end_use_consumptions', user_arguments)
478
- include_timeseries_emissions = runner.getOptionalBoolArgumentValue('include_timeseries_emissions', user_arguments)
479
- include_timeseries_emission_fuels = runner.getOptionalBoolArgumentValue('include_timeseries_emission_fuels', user_arguments)
480
- include_timeseries_emission_end_uses = runner.getOptionalBoolArgumentValue('include_timeseries_emission_end_uses', user_arguments)
481
- include_timeseries_hot_water_uses = runner.getOptionalBoolArgumentValue('include_timeseries_hot_water_uses', user_arguments)
482
- include_timeseries_total_loads = runner.getOptionalBoolArgumentValue('include_timeseries_total_loads', user_arguments)
483
- include_timeseries_component_loads = runner.getOptionalBoolArgumentValue('include_timeseries_component_loads', user_arguments)
484
- include_timeseries_unmet_hours = runner.getOptionalBoolArgumentValue('include_timeseries_unmet_hours', user_arguments)
485
- include_timeseries_zone_temperatures = runner.getOptionalBoolArgumentValue('include_timeseries_zone_temperatures', user_arguments)
486
- include_timeseries_airflows = runner.getOptionalBoolArgumentValue('include_timeseries_airflows', user_arguments)
487
- include_timeseries_weather = runner.getOptionalBoolArgumentValue('include_timeseries_weather', user_arguments)
488
- use_timestamp_start_convention = (runner.getStringArgumentValue('timeseries_timestamp_convention', user_arguments) == 'start')
489
- add_timeseries_dst_column = runner.getOptionalBoolArgumentValue('add_timeseries_dst_column', user_arguments)
490
- add_timeseries_utc_column = runner.getOptionalBoolArgumentValue('add_timeseries_utc_column', user_arguments)
491
- user_output_variables = runner.getOptionalStringArgumentValue('user_output_variables', user_arguments)
492
-
493
- include_timeseries_total_consumptions = include_timeseries_total_consumptions.is_initialized ? include_timeseries_total_consumptions.get : false
494
- include_timeseries_fuel_consumptions = include_timeseries_fuel_consumptions.is_initialized ? include_timeseries_fuel_consumptions.get : false
495
- include_timeseries_end_use_consumptions = include_timeseries_end_use_consumptions.is_initialized ? include_timeseries_end_use_consumptions.get : false
496
- include_timeseries_emissions = include_timeseries_emissions.is_initialized ? include_timeseries_emissions.get : false
497
- include_timeseries_emission_fuels = include_timeseries_emission_fuels.is_initialized ? include_timeseries_emission_fuels.get : false
498
- include_timeseries_emission_end_uses = include_timeseries_emission_end_uses.is_initialized ? include_timeseries_emission_end_uses.get : false
499
- include_timeseries_hot_water_uses = include_timeseries_hot_water_uses.is_initialized ? include_timeseries_hot_water_uses.get : false
500
- include_timeseries_total_loads = include_timeseries_total_loads.is_initialized ? include_timeseries_total_loads.get : false
501
- include_timeseries_component_loads = include_timeseries_component_loads.is_initialized ? include_timeseries_component_loads.get : false
502
- include_timeseries_unmet_hours = include_timeseries_unmet_hours.is_initialized ? include_timeseries_unmet_hours.get : false
503
- include_timeseries_zone_temperatures = include_timeseries_zone_temperatures.is_initialized ? include_timeseries_zone_temperatures.get : false
504
- include_timeseries_airflows = include_timeseries_airflows.is_initialized ? include_timeseries_airflows.get : false
505
- include_timeseries_weather = include_timeseries_weather.is_initialized ? include_timeseries_weather.get : false
506
- user_output_variables = user_output_variables.is_initialized ? user_output_variables.get : nil
507
- end
508
- generate_eri_outputs = runner.getOptionalBoolArgumentValue('generate_eri_outputs', user_arguments)
509
- generate_eri_outputs = generate_eri_outputs.is_initialized ? generate_eri_outputs.get : false
510
- annual_output_file_name = runner.getOptionalStringArgumentValue('annual_output_file_name', user_arguments)
511
- timeseries_output_file_name = runner.getOptionalStringArgumentValue('timeseries_output_file_name', user_arguments)
494
+ args = get_arguments(runner, arguments(model), user_arguments)
495
+
496
+ if args[:output_format] == 'csv_dview'
497
+ args[:output_format] = 'csv'
498
+ args[:use_dview_format] = true
499
+ else
500
+ args[:use_dview_format] = false
501
+ end
512
502
 
513
503
  output_dir = File.dirname(runner.lastEpwFilePath.get.to_s)
514
504
 
515
505
  hpxml_defaults_path = @model.getBuilding.additionalProperties.getFeatureAsString('hpxml_defaults_path').get
516
506
  building_id = @model.getBuilding.additionalProperties.getFeatureAsString('building_id').get
517
507
  @hpxml = HPXML.new(hpxml_path: hpxml_defaults_path, building_id: building_id)
518
- HVAC.apply_shared_systems(@hpxml) # Needed for ERI shared HVAC systems
519
508
 
520
- setup_outputs(false, user_output_variables)
509
+ setup_outputs(false, args[:user_output_variables])
521
510
 
522
511
  if not File.exist? File.join(output_dir, 'eplusout.msgpack')
523
512
  runner.registerError('Cannot find eplusout.msgpack.')
@@ -525,7 +514,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
525
514
  end
526
515
  @msgpackData = MessagePack.unpack(File.read(File.join(output_dir, 'eplusout.msgpack'), mode: 'rb'))
527
516
  @msgpackDataRunPeriod = MessagePack.unpack(File.read(File.join(output_dir, 'eplusout_runperiod.msgpack'), mode: 'rb'))
528
- msgpack_timeseries_path = File.join(output_dir, "eplusout_#{timeseries_frequency}.msgpack")
517
+ msgpack_timeseries_path = File.join(output_dir, "eplusout_#{args[:timeseries_frequency]}.msgpack")
529
518
  if File.exist? msgpack_timeseries_path
530
519
  @msgpackDataTimeseries = MessagePack.unpack(File.read(msgpack_timeseries_path, mode: 'rb'))
531
520
  end
@@ -534,137 +523,140 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
534
523
  end
535
524
 
536
525
  # Set paths
537
- if annual_output_file_name.is_initialized
538
- annual_output_path = File.join(output_dir, annual_output_file_name.get)
526
+ if not args[:annual_output_file_name].nil?
527
+ annual_output_path = File.join(output_dir, args[:annual_output_file_name])
539
528
  else
540
- annual_output_path = File.join(output_dir, "results_annual.#{output_format}")
529
+ annual_output_path = File.join(output_dir, "results_annual.#{args[:output_format]}")
541
530
  end
542
- if timeseries_output_file_name.is_initialized
543
- timeseries_output_path = File.join(output_dir, timeseries_output_file_name.get)
531
+ if not args[:timeseries_output_file_name].nil?
532
+ timeseries_output_path = File.join(output_dir, args[:timeseries_output_file_name])
544
533
  else
545
- timeseries_output_path = File.join(output_dir, "results_timeseries.#{output_format}")
534
+ timeseries_output_path = File.join(output_dir, "results_timeseries.#{args[:output_format]}")
546
535
  end
547
536
 
548
- if timeseries_frequency != 'none'
549
- add_dst_column = (add_timeseries_dst_column.is_initialized ? add_timeseries_dst_column.get : false)
550
- add_utc_column = (add_timeseries_utc_column.is_initialized ? add_timeseries_utc_column.get : false)
551
- @timestamps, timestamps_dst, timestamps_utc = OutputMethods.get_timestamps(@msgpackDataTimeseries, @hpxml, use_timestamp_start_convention,
552
- add_dst_column, add_utc_column, use_dview_format, timeseries_frequency)
537
+ if args[:timeseries_frequency] != 'none'
538
+ @timestamps, timestamps_dst, timestamps_utc = get_timestamps(@msgpackDataTimeseries, @hpxml, args)
553
539
  end
554
540
 
555
541
  # Retrieve outputs
556
- outputs = get_outputs(runner, timeseries_frequency,
557
- include_timeseries_total_consumptions,
558
- include_timeseries_fuel_consumptions,
559
- include_timeseries_end_use_consumptions,
560
- include_timeseries_emissions,
561
- include_timeseries_emission_fuels,
562
- include_timeseries_emission_end_uses,
563
- include_timeseries_hot_water_uses,
564
- include_timeseries_total_loads,
565
- include_timeseries_component_loads,
566
- include_timeseries_unmet_hours,
567
- include_timeseries_zone_temperatures,
568
- include_timeseries_airflows,
569
- include_timeseries_weather)
542
+ outputs = get_outputs(runner, args)
570
543
 
571
544
  if not check_for_errors(runner, outputs)
572
545
  return false
573
546
  end
574
547
 
575
- # Set rounding precision for run period (e.g., annual) outputs.
576
- # Note: Make sure to round outputs with sufficient resolution for the worst case -- i.e., 1 day instead of a full year.
577
- runperiod_n_digits = 3 # Default for annual (or near-annual) data
578
- sim_n_days = (Schedule.get_day_num_from_month_day(2000, @hpxml.header.sim_end_month, @hpxml.header.sim_end_day) -
579
- Schedule.get_day_num_from_month_day(2000, @hpxml.header.sim_begin_month, @hpxml.header.sim_begin_day))
580
- if sim_n_days <= 10 # 10 days or less; add two decimal places
581
- runperiod_n_digits += 2
582
- elsif sim_n_days <= 100 # 100 days or less; add one decimal place
583
- runperiod_n_digits += 1
584
- end
585
-
586
548
  # Write/report results
587
- report_runperiod_output_results(runner, outputs, output_format, annual_output_path, runperiod_n_digits, generate_eri_outputs)
588
- report_timeseries_output_results(runner, outputs, output_format,
589
- timeseries_output_path,
590
- timeseries_frequency,
591
- include_timeseries_total_consumptions,
592
- include_timeseries_fuel_consumptions,
593
- include_timeseries_end_use_consumptions,
594
- include_timeseries_emissions,
595
- include_timeseries_emission_fuels,
596
- include_timeseries_emission_end_uses,
597
- include_timeseries_hot_water_uses,
598
- include_timeseries_total_loads,
599
- include_timeseries_component_loads,
600
- include_timeseries_unmet_hours,
601
- include_timeseries_zone_temperatures,
602
- include_timeseries_airflows,
603
- include_timeseries_weather,
604
- add_dst_column,
605
- add_utc_column,
606
- timestamps_dst,
607
- timestamps_utc,
608
- use_dview_format)
549
+ report_runperiod_output_results(runner, outputs, args, annual_output_path)
550
+ report_timeseries_output_results(runner, outputs, timeseries_output_path, args, timestamps_dst, timestamps_utc)
609
551
 
610
552
  return true
611
553
  end
612
554
 
613
- def get_outputs(runner, timeseries_frequency,
614
- include_timeseries_total_consumptions,
615
- include_timeseries_fuel_consumptions,
616
- include_timeseries_end_use_consumptions,
617
- include_timeseries_emissions,
618
- include_timeseries_emission_fuels,
619
- include_timeseries_emission_end_uses,
620
- include_timeseries_hot_water_uses,
621
- include_timeseries_total_loads,
622
- include_timeseries_component_loads,
623
- include_timeseries_unmet_hours,
624
- include_timeseries_zone_temperatures,
625
- include_timeseries_airflows,
626
- include_timeseries_weather)
627
- outputs = {}
555
+ def get_timestamps(msgpackData, hpxml, args)
556
+ return if msgpackData.nil?
557
+
558
+ ep_timestamps = msgpackData['Rows'].map { |r| r.keys[0] }
559
+
560
+ 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)
563
+ end
564
+ if args[:add_timeseries_utc_column]
565
+ utc_offset = hpxml.header.time_zone_utc_offset
566
+ utc_offset *= 3600 # seconds
567
+ end
568
+
569
+ timestamps = []
570
+ timestamps_dst = [] if args[:add_timeseries_dst_column] || args[:use_dview_format]
571
+ timestamps_utc = [] if args[:add_timeseries_utc_column]
572
+ year = hpxml.header.sim_calendar_year
573
+ ep_timestamps.each do |ep_timestamp|
574
+ month_day, hour_minute = ep_timestamp.split(' ')
575
+ month, day = month_day.split('/').map(&:to_i)
576
+ hour, minute, _ = hour_minute.split(':').map(&:to_i)
577
+
578
+ # Convert from EnergyPlus default (end-of-timestep) to start-of-timestep convention
579
+ if args[:timeseries_timestamp_convention] == 'start'
580
+ if args[:timeseries_frequency] == 'timestep'
581
+ ts_offset = hpxml.header.timestep * 60 # seconds
582
+ elsif args[:timeseries_frequency] == 'hourly'
583
+ ts_offset = 60 * 60 # seconds
584
+ elsif args[:timeseries_frequency] == 'daily'
585
+ ts_offset = 60 * 60 * 24 # seconds
586
+ elsif args[:timeseries_frequency] == 'monthly'
587
+ ts_offset = Constants.NumDaysInMonths(year)[month - 1] * 60 * 60 * 24 # seconds
588
+ else
589
+ fail "Unexpected timeseries_frequency: #{args[:timeseries_frequency]}."
590
+ end
591
+ end
628
592
 
629
- # To calculate timeseries emissions or timeseries fuel consumption, we also need to select timeseries
630
- # end use consumption because EnergyPlus results may be post-processed due to, e.g., HVAC DSE.
631
- # TODO: This could be removed if we could account for DSE inside EnergyPlus.
632
- if not @emissions.empty?
633
- include_hourly_electric_end_use_consumptions = true # For annual Cambium calculation
634
- if include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
635
- include_timeseries_fuel_consumptions = true
593
+ ts = Time.utc(year, month, day, hour, minute)
594
+ ts -= ts_offset unless ts_offset.nil?
595
+
596
+ timestamps << ts.iso8601.delete('Z')
597
+
598
+ if args[:add_timeseries_dst_column] || args[:use_dview_format]
599
+ if (ts >= dst_start_ts) && (ts < dst_end_ts)
600
+ ts_dst = ts + 3600 # 1 hr shift forward
601
+ else
602
+ ts_dst = ts
603
+ end
604
+ timestamps_dst << ts_dst.iso8601.delete('Z')
605
+ end
606
+
607
+ if args[:add_timeseries_utc_column]
608
+ ts_utc = ts - utc_offset
609
+ timestamps_utc << ts_utc.iso8601
636
610
  end
637
- end
638
- if include_timeseries_total_consumptions
639
- include_timeseries_fuel_consumptions = true
640
- end
641
- if include_timeseries_fuel_consumptions
642
- include_timeseries_end_use_consumptions = true
643
611
  end
644
612
 
613
+ return timestamps, timestamps_dst, timestamps_utc
614
+ end
615
+
616
+ def get_outputs(runner, args)
617
+ outputs = {}
618
+
619
+ args = setup_timeseries_includes(@emissions, args)
620
+
645
621
  # Fuel Uses
646
622
  @fuels.each do |fuel_type, fuel|
647
623
  fuel.annual_output = get_report_meter_data_annual(fuel.meters)
648
624
  fuel.annual_output -= get_report_meter_data_annual(['ElectricStorage:ElectricityProduced']) if fuel_type == FT::Elec # We add Electric Storage onto the annual Electricity fuel meter
649
625
 
650
- next unless include_timeseries_fuel_consumptions
626
+ next unless args[:include_timeseries_fuel_consumptions]
627
+
628
+ fuel.timeseries_output = get_report_meter_data_timeseries(fuel.meters, UnitConversions.convert(1.0, 'J', fuel.timeseries_units), 0, args[:timeseries_frequency])
651
629
 
652
- fuel.timeseries_output = get_report_meter_data_timeseries(fuel.meters, UnitConversions.convert(1.0, 'J', fuel.timeseries_units), 0, timeseries_frequency)
653
- fuel.timeseries_output = fuel.timeseries_output.zip(get_report_meter_data_timeseries(['ElectricStorage:ElectricityProduced'], UnitConversions.convert(1.0, 'J', fuel.timeseries_units), 0, timeseries_frequency)).map { |x, y| x - y } if fuel_type == FT::Elec # We add Electric Storage onto the timeseries Electricity fuel meter
630
+ next unless fuel_type == FT::Elec
631
+
632
+ # We add Electric Storage onto the timeseries Electricity fuel meter
633
+ elec_storage_timeseries_output = get_report_meter_data_timeseries(['ElectricStorage:ElectricityProduced'], UnitConversions.convert(1.0, 'J', fuel.timeseries_units), 0, args[:timeseries_frequency])
634
+ fuel.timeseries_output = fuel.timeseries_output.zip(elec_storage_timeseries_output).map { |x, y| x - y }
654
635
  end
655
636
 
656
637
  # Peak Electricity Consumption
657
- @peak_fuels.each do |_key, peak_fuel|
658
- peak_fuel.annual_output = get_tabular_data_value(peak_fuel.report.upcase, 'Meter', 'Custom Monthly Report', ['Maximum of Months'], 'ELECTRICITY:FACILITY {MAX FOR HOURS SHOWN}', peak_fuel.annual_units)
638
+ is_southern_hemisphere = @model.getBuilding.additionalProperties.getFeatureAsBoolean('is_southern_hemisphere').get
639
+ is_northern_hemisphere = !is_southern_hemisphere
640
+ @peak_fuels.each do |key, peak_fuel|
641
+ _fuel, season = key
642
+ if (season == PFT::Summer && is_northern_hemisphere) || (season == PFT::Winter && is_southern_hemisphere)
643
+ months = ['June', 'July', 'August']
644
+ elsif (season == PFT::Winter && is_northern_hemisphere) || (season == PFT::Summer && is_southern_hemisphere)
645
+ months = ['December', 'January', 'February']
646
+ end
647
+ for month in months
648
+ val = get_tabular_data_value(peak_fuel.report.upcase, 'Meter', 'Custom Monthly Report', [month], 'ELECTRICITY:FACILITY {Maximum}', peak_fuel.annual_units)
649
+ peak_fuel.annual_output = [peak_fuel.annual_output.to_f, val].max
650
+ end
659
651
  end
660
652
 
661
653
  # Total loads
662
- @loads.each do |load_type, load|
654
+ @loads.each do |_load_type, load|
663
655
  if not load.ems_variable.nil?
664
656
  # Obtain from EMS output variable
665
657
  load.annual_output = get_report_variable_data_annual(['EMS'], ["#{load.ems_variable}_annual_outvar"])
666
- if include_timeseries_total_loads
667
- load.timeseries_output = get_report_variable_data_timeseries(['EMS'], ["#{load.ems_variable}_timeseries_outvar"], UnitConversions.convert(1.0, 'J', load.timeseries_units), 0, timeseries_frequency, ems_shift: true)
658
+ if args[:include_timeseries_total_loads]
659
+ load.timeseries_output = get_report_variable_data_timeseries(['EMS'], ["#{load.ems_variable}_timeseries_outvar"], UnitConversions.convert(1.0, 'J', load.timeseries_units), 0, args[:timeseries_frequency], ems_shift: true)
668
660
  end
669
661
  elsif load.variables.size > 0
670
662
  # Obtain from output variable
@@ -673,8 +665,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
673
665
  vars = load.variables.select { |v| v[0] == sys_id }.map { |v| v[2] }
674
666
 
675
667
  load.annual_output_by_system[sys_id] = get_report_variable_data_annual(keys, vars, is_negative: load.is_negative)
676
- if include_timeseries_total_loads && (load_type == LT::HotWaterDelivered)
677
- load.timeseries_output_by_system[sys_id] = get_report_variable_data_timeseries(keys, vars, UnitConversions.convert(1.0, 'J', load.timeseries_units), 0, timeseries_frequency, is_negative: load.is_negative, ems_shift: true)
668
+ if args[:include_timeseries_total_loads]
669
+ load.timeseries_output_by_system[sys_id] = get_report_variable_data_timeseries(keys, vars, UnitConversions.convert(1.0, 'J', load.timeseries_units), 0, args[:timeseries_frequency], is_negative: load.is_negative, ems_shift: true)
678
670
  end
679
671
  end
680
672
  end
@@ -683,26 +675,16 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
683
675
  # Component Loads
684
676
  @component_loads.each do |_key, comp_load|
685
677
  comp_load.annual_output = get_report_variable_data_annual(['EMS'], ["#{comp_load.ems_variable}_annual_outvar"])
686
- if include_timeseries_component_loads
687
- comp_load.timeseries_output = get_report_variable_data_timeseries(['EMS'], ["#{comp_load.ems_variable}_timeseries_outvar"], UnitConversions.convert(1.0, 'J', comp_load.timeseries_units), 0, timeseries_frequency, ems_shift: true)
678
+ if args[:include_timeseries_component_loads]
679
+ comp_load.timeseries_output = get_report_variable_data_timeseries(['EMS'], ["#{comp_load.ems_variable}_timeseries_outvar"], UnitConversions.convert(1.0, 'J', comp_load.timeseries_units), 0, args[:timeseries_frequency], ems_shift: true)
688
680
  end
689
681
  end
690
682
 
691
683
  # Unmet Hours
692
684
  @unmet_hours.each do |_key, unmet_hour|
693
685
  unmet_hour.annual_output = get_report_variable_data_annual(['EMS'], ["#{unmet_hour.ems_variable}_annual_outvar"], 1.0)
694
- if include_timeseries_unmet_hours
695
- unmet_hour.timeseries_output = get_report_variable_data_timeseries(['EMS'], ["#{unmet_hour.ems_variable}_timeseries_outvar"], 1.0, 0, timeseries_frequency)
696
- end
697
- end
698
-
699
- # Ideal system loads (expected fraction of loads that are not met by partial HVAC (e.g., room AC that meets 30% of load))
700
- @ideal_system_loads.each do |_load_type, ideal_load|
701
- ideal_load.variables.map { |v| v[0] }.uniq.each do |sys_id|
702
- keys = ideal_load.variables.select { |v| v[0] == sys_id }.map { |v| v[1] }
703
- vars = ideal_load.variables.select { |v| v[0] == sys_id }.map { |v| v[2] }
704
-
705
- ideal_load.annual_output = get_report_variable_data_annual(keys, vars)
686
+ if args[:include_timeseries_unmet_hours]
687
+ unmet_hour.timeseries_output = get_report_variable_data_timeseries(['EMS'], ["#{unmet_hour.ems_variable}_timeseries_outvar"], 1.0, 0, args[:timeseries_frequency])
706
688
  end
707
689
  end
708
690
 
@@ -721,10 +703,10 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
721
703
 
722
704
  end_use.annual_output_by_system[sys_id] = get_report_variable_data_annual(keys, vars, is_negative: (end_use.is_negative || end_use.is_storage))
723
705
 
724
- if include_timeseries_end_use_consumptions
725
- end_use.timeseries_output_by_system[sys_id] = get_report_variable_data_timeseries(keys, vars, UnitConversions.convert(1.0, 'J', end_use.timeseries_units), 0, timeseries_frequency, is_negative: (end_use.is_negative || end_use.is_storage))
706
+ if args[:include_timeseries_end_use_consumptions]
707
+ end_use.timeseries_output_by_system[sys_id] = get_report_variable_data_timeseries(keys, vars, UnitConversions.convert(1.0, 'J', end_use.timeseries_units), 0, args[:timeseries_frequency], is_negative: (end_use.is_negative || end_use.is_storage))
726
708
  end
727
- if include_hourly_electric_end_use_consumptions && fuel_type == FT::Elec
709
+ if args[:include_hourly_electric_end_use_consumptions] && fuel_type == FT::Elec
728
710
  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))
729
711
  end
730
712
  end
@@ -734,16 +716,20 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
734
716
  # applying proportionally to the GSHP heating & cooling fan/pump energy use.
735
717
  gshp_shared_loop_end_use = @end_uses[[FT::Elec, 'TempGSHPSharedPump']]
736
718
  htg_fan_pump_end_use = @end_uses[[FT::Elec, EUT::HeatingFanPump]]
719
+ backup_htg_fan_pump_end_use = @end_uses[[FT::Elec, EUT::HeatingHeatPumpBackupFanPump]]
737
720
  clg_fan_pump_end_use = @end_uses[[FT::Elec, EUT::CoolingFanPump]]
738
721
  gshp_shared_loop_end_use.annual_output_by_system.keys.each do |sys_id|
739
722
  # Calculate heating & cooling fan/pump end use multiplier
740
- htg_energy = htg_fan_pump_end_use.annual_output_by_system[sys_id]
741
- clg_energy = clg_fan_pump_end_use.annual_output_by_system[sys_id]
723
+ htg_energy = htg_fan_pump_end_use.annual_output_by_system[sys_id].to_f + backup_htg_fan_pump_end_use.annual_output_by_system[sys_id].to_f
724
+ clg_energy = clg_fan_pump_end_use.annual_output_by_system[sys_id].to_f
742
725
  shared_pump_energy = gshp_shared_loop_end_use.annual_output_by_system[sys_id]
743
726
  energy_multiplier = (htg_energy + clg_energy + shared_pump_energy) / (htg_energy + clg_energy)
744
727
  # Apply multiplier
745
- apply_multiplier_to_output(htg_fan_pump_end_use, nil, sys_id, energy_multiplier)
746
- apply_multiplier_to_output(clg_fan_pump_end_use, nil, sys_id, energy_multiplier)
728
+ [htg_fan_pump_end_use, backup_htg_fan_pump_end_use, clg_fan_pump_end_use].each do |end_use|
729
+ next if end_use.annual_output_by_system[sys_id].nil?
730
+
731
+ apply_multiplier_to_output(end_use, nil, sys_id, energy_multiplier)
732
+ end
747
733
  end
748
734
  @end_uses.delete([FT::Elec, 'TempGSHPSharedPump'])
749
735
 
@@ -754,8 +740,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
754
740
  vars = hot_water.variables.select { |v| v[0] == sys_id }.map { |v| v[2] }
755
741
 
756
742
  hot_water.annual_output_by_system[sys_id] = get_report_variable_data_annual(keys, vars, UnitConversions.convert(1.0, 'm^3', hot_water.annual_units))
757
- if include_timeseries_hot_water_uses
758
- hot_water.timeseries_output_by_system[sys_id] = get_report_variable_data_timeseries(keys, vars, UnitConversions.convert(1.0, 'm^3', hot_water.timeseries_units), 0, timeseries_frequency)
743
+ if args[:include_timeseries_hot_water_uses]
744
+ hot_water.timeseries_output_by_system[sys_id] = get_report_variable_data_timeseries(keys, vars, UnitConversions.convert(1.0, 'm^3', hot_water.timeseries_units), 0, args[:timeseries_frequency])
759
745
  end
760
746
  end
761
747
  end
@@ -769,16 +755,13 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
769
755
 
770
756
  dse = htg_system.distribution_system.annual_heating_dse
771
757
  @fuels.each do |fuel_type, fuel|
772
- [EUT::Heating, EUT::HeatingHeatPumpBackup, EUT::HeatingFanPump].each do |end_use_type|
758
+ [EUT::Heating, EUT::HeatingHeatPumpBackup, EUT::HeatingFanPump, EUT::HeatingHeatPumpBackupFanPump].each do |end_use_type|
773
759
  end_use = @end_uses[[fuel_type, end_use_type]]
774
760
  next if end_use.nil?
775
761
 
776
762
  if not end_use.annual_output_by_system[htg_system.id].nil?
777
763
  apply_multiplier_to_output(end_use, fuel, htg_system.id, 1.0 / dse)
778
764
  end
779
- if not end_use.annual_output_by_system[htg_system.id + '_DFHPBackup'].nil?
780
- apply_multiplier_to_output(end_use, fuel, htg_system.id + '_DFHPBackup', 1.0 / dse)
781
- end
782
765
  end
783
766
  end
784
767
  end
@@ -817,6 +800,30 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
817
800
  end
818
801
  end
819
802
 
803
+ # Calculate System Uses from End Uses (by HPXML System)
804
+ @system_uses = {}
805
+ get_hpxml_system_ids.each do |sys_id|
806
+ @end_uses.each do |eu_key, end_use|
807
+ annual_output = end_use.annual_output_by_system[sys_id].to_f
808
+ next if annual_output <= 0
809
+
810
+ system_use_output = BaseOutput.new
811
+ @system_uses[[sys_id, eu_key]] = system_use_output
812
+ fuel_type, end_use_type = eu_key
813
+ system_use_output.name = "System Use: #{sys_id}: #{fuel_type}: #{end_use_type}"
814
+
815
+ # Annual
816
+ system_use_output.annual_output = annual_output
817
+ system_use_output.annual_units = end_use.annual_units
818
+
819
+ next unless args[:include_timeseries_system_use_consumptions]
820
+
821
+ # Timeseries
822
+ system_use_output.timeseries_output = end_use.timeseries_output_by_system[sys_id]
823
+ system_use_output.timeseries_units = end_use.timeseries_units
824
+ end
825
+ end
826
+
820
827
  # Calculate aggregated values from per-system values as needed
821
828
  (@end_uses.values + @loads.values + @hot_water_uses.values).each do |obj|
822
829
  # Annual
@@ -830,29 +837,22 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
830
837
 
831
838
  # Timeseries
832
839
  if obj.timeseries_output.empty? && (not obj.timeseries_output_by_system.empty?)
833
- obj.timeseries_output = obj.timeseries_output_by_system.values[0]
834
- obj.timeseries_output_by_system.values[1..-1].each do |values|
835
- obj.timeseries_output = obj.timeseries_output.zip(values).map { |x, y| x + y }
836
- end
840
+ obj.timeseries_output = obj.timeseries_output_by_system.values.transpose.map(&:sum)
837
841
  end
838
842
 
839
843
  # Hourly Electricity (for Cambium)
840
844
  next unless obj.is_a?(EndUse) && obj.hourly_output.empty? && (not obj.hourly_output_by_system.empty?)
841
845
 
842
- obj.hourly_output = obj.hourly_output_by_system.values[0]
843
- obj.hourly_output_by_system.values[1..-1].each do |values|
844
- obj.hourly_output = obj.hourly_output.zip(values).map { |x, y| x + y }
845
- end
846
+ obj.hourly_output = obj.hourly_output_by_system.values.transpose.map(&:sum)
846
847
  end
847
848
 
848
849
  # Total/Net Electricity (Net includes, e.g., PV and generators)
849
850
  outputs[:elec_prod_annual] = @end_uses.select { |k, eu| k[0] == FT::Elec && eu.is_negative }.map { |_k, eu| eu.annual_output.to_f }.sum(0.0) # Negative value
850
851
  outputs[:elec_net_annual] = @fuels[FT::Elec].annual_output.to_f + outputs[:elec_prod_annual]
851
- if include_timeseries_fuel_consumptions
852
- outputs[:elec_prod_timeseries] = [0.0] * @timestamps.size # Negative values
853
- @end_uses.select { |k, eu| k[0] == FT::Elec && eu.is_negative && eu.timeseries_output.size > 0 }.each do |_key, end_use|
854
- outputs[:elec_prod_timeseries] = outputs[:elec_prod_timeseries].zip(end_use.timeseries_output).map { |x, y| x + y }
855
- end
852
+ if args[:include_timeseries_fuel_consumptions]
853
+ prod_end_uses = @end_uses.select { |k, eu| k[0] == FT::Elec && eu.is_negative && eu.timeseries_output.size > 0 }.map { |_k, v| v.timeseries_output }
854
+ outputs[:elec_prod_timeseries] = prod_end_uses.transpose.map(&:sum)
855
+ outputs[:elec_prod_timeseries] = [0.0] * @timestamps.size if outputs[:elec_prod_timeseries].empty?
856
856
  outputs[:elec_net_timeseries] = @fuels[FT::Elec].timeseries_output.zip(outputs[:elec_prod_timeseries]).map { |x, y| x + y }
857
857
  end
858
858
 
@@ -860,20 +860,20 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
860
860
  @totals[TE::Total].annual_output = 0.0
861
861
  @fuels.each do |_fuel_type, fuel|
862
862
  @totals[TE::Total].annual_output += fuel.annual_output
863
- next unless include_timeseries_total_consumptions && fuel.timeseries_output.sum != 0.0
863
+ next unless args[:include_timeseries_total_consumptions] && fuel.timeseries_output.sum != 0.0
864
864
 
865
865
  @totals[TE::Total].timeseries_output = [0.0] * @timestamps.size if @totals[TE::Total].timeseries_output.empty?
866
866
  unit_conv = UnitConversions.convert(1.0, fuel.timeseries_units, @totals[TE::Total].timeseries_units)
867
867
  @totals[TE::Total].timeseries_output = @totals[TE::Total].timeseries_output.zip(fuel.timeseries_output).map { |x, y| x + y * unit_conv }
868
868
  end
869
869
  @totals[TE::Net].annual_output = @totals[TE::Total].annual_output + outputs[:elec_prod_annual]
870
- if include_timeseries_total_consumptions
870
+ if args[:include_timeseries_total_consumptions]
871
871
  unit_conv = UnitConversions.convert(1.0, get_timeseries_units_from_fuel_type(FT::Elec), @totals[TE::Total].timeseries_units)
872
872
  @totals[TE::Net].timeseries_output = @totals[TE::Total].timeseries_output.zip(outputs[:elec_prod_timeseries]).map { |x, y| x + y * unit_conv }
873
873
  end
874
874
 
875
875
  # Zone temperatures
876
- if include_timeseries_zone_temperatures
876
+ if args[:include_timeseries_zone_temperatures]
877
877
  zone_names = []
878
878
  scheduled_temperature_names = []
879
879
  @model.getThermalZones.each do |zone|
@@ -891,32 +891,32 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
891
891
  @zone_temps[zone_name] = ZoneTemp.new
892
892
  @zone_temps[zone_name].name = "Temperature: #{zone_name.split.map(&:capitalize).join(' ')}"
893
893
  @zone_temps[zone_name].timeseries_units = 'F'
894
- @zone_temps[zone_name].timeseries_output = get_report_variable_data_timeseries([zone_name], ['Zone Mean Air Temperature'], 9.0 / 5.0, 32.0, timeseries_frequency)
894
+ @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
895
  end
896
896
  scheduled_temperature_names.sort.each do |scheduled_temperature_name|
897
897
  @zone_temps[scheduled_temperature_name] = ZoneTemp.new
898
898
  @zone_temps[scheduled_temperature_name].name = "Temperature: #{scheduled_temperature_name.split.map(&:capitalize).join(' ')}"
899
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, timeseries_frequency)
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])
901
901
  end
902
902
  { 'Heating Setpoint' => 'Zone Thermostat Heating Setpoint Temperature',
903
903
  'Cooling Setpoint' => 'Zone Thermostat Cooling Setpoint Temperature' }.each do |sp_name, sp_var|
904
904
  @zone_temps[sp_name] = ZoneTemp.new
905
905
  @zone_temps[sp_name].name = "Temperature: #{sp_name}"
906
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, timeseries_frequency)
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])
908
908
  end
909
909
  end
910
910
 
911
911
  # Airflows
912
- if include_timeseries_airflows
912
+ if args[:include_timeseries_airflows]
913
913
  @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, timeseries_frequency)
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])
915
915
  end
916
916
  end
917
917
 
918
918
  # Weather
919
- if include_timeseries_weather
919
+ if args[:include_timeseries_weather]
920
920
  @weather.each do |_weather_type, weather_data|
921
921
  if weather_data.timeseries_units == 'F'
922
922
  unit_conv = 9.0 / 5.0
@@ -925,7 +925,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
925
925
  unit_conv = UnitConversions.convert(1.0, weather_data.variable_units, weather_data.timeseries_units)
926
926
  unit_adder = 0
927
927
  end
928
- weather_data.timeseries_output = get_report_variable_data_timeseries(['Environment'], [weather_data.variable], unit_conv, unit_adder, timeseries_frequency)
928
+ weather_data.timeseries_output = get_report_variable_data_timeseries(['Environment'], [weather_data.variable], unit_conv, unit_adder, args[:timeseries_frequency])
929
929
  end
930
930
  end
931
931
 
@@ -937,7 +937,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
937
937
  @output_variables[[output_variable_name, key_value]] = OutputVariable.new
938
938
  @output_variables[[output_variable_name, key_value]].name = "#{output_variable_name}: #{key_value.split.map(&:capitalize).join(' ')}"
939
939
  @output_variables[[output_variable_name, key_value]].timeseries_units = units
940
- @output_variables[[output_variable_name, key_value]].timeseries_output = get_report_variable_data_timeseries([key_value], [output_variable_name], 1, 0, timeseries_frequency)
940
+ @output_variables[[output_variable_name, key_value]].timeseries_output = get_report_variable_data_timeseries([key_value], [output_variable_name], 1, 0, args[:timeseries_frequency])
941
941
  end
942
942
  end
943
943
 
@@ -996,22 +996,18 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
996
996
  end
997
997
  @emissions[key].annual_output_by_end_use[eu_key] = hourly_elec.zip(hourly_elec_factors).map { |x, y| x * y * kwh_to_mwh * elec_units_mult }.sum
998
998
 
999
- next unless include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
999
+ next unless args[:include_timeseries_emissions] || args[:include_timeseries_emission_end_uses] || args[:include_timeseries_emission_fuels]
1000
1000
 
1001
1001
  # Calculate timeseries emissions for end use
1002
1002
 
1003
- if timeseries_frequency == 'timestep' && @hpxml.header.timestep != 60
1004
- timeseries_elec = nil
1005
- end_use.timeseries_output_by_system.each do |_sys_id, timeseries_output|
1006
- timeseries_elec = [0.0] * timeseries_output.size if timeseries_elec.nil?
1007
- timeseries_elec = timeseries_elec.zip(timeseries_output.map { |x| x * kwh_to_mwh }).map { |x, y| x + y }
1008
- end
1003
+ if args[:timeseries_frequency] == 'timestep' && @hpxml.header.timestep != 60
1004
+ timeseries_elec = end_use.timeseries_output_by_system.values.transpose.map(&:sum).map { |x| x * kwh_to_mwh }
1009
1005
  else
1010
1006
  # Need to perform calculations hourly at a minimum
1011
1007
  timeseries_elec = end_use.hourly_output.map { |x| x * kwh_to_mwh }
1012
1008
  end
1013
1009
 
1014
- if timeseries_frequency == 'timestep'
1010
+ if args[:timeseries_frequency] == 'timestep'
1015
1011
  n_timesteps_per_hour = Integer(60.0 / @hpxml.header.timestep)
1016
1012
  timeseries_elec_factors = hourly_elec_factors.flat_map { |y| [y] * n_timesteps_per_hour }
1017
1013
  else
@@ -1022,11 +1018,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1022
1018
  @emissions[key].timeseries_output_by_end_use[eu_key] = timeseries_elec.zip(timeseries_elec_factors).map { |n, f| n * f * elec_units_mult }
1023
1019
 
1024
1020
  # Aggregate up from hourly to the desired timeseries frequency
1025
- next unless ['daily', 'monthly'].include? timeseries_frequency
1021
+ next unless ['daily', 'monthly'].include? args[:timeseries_frequency]
1026
1022
 
1027
- if timeseries_frequency == 'daily'
1023
+ if args[:timeseries_frequency] == 'daily'
1028
1024
  n_hours_per_period = [24] * (sim_end_day_of_year - sim_start_day_of_year + 1)
1029
- elsif timeseries_frequency == 'monthly'
1025
+ elsif args[:timeseries_frequency] == 'monthly'
1030
1026
  n_days_per_month = Constants.NumDaysInMonths(year)
1031
1027
  n_days_per_period = n_days_per_month[@hpxml.header.sim_begin_month - 1..@hpxml.header.sim_end_month - 1]
1032
1028
  n_days_per_period[0] -= @hpxml.header.sim_begin_day - 1
@@ -1069,41 +1065,45 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1069
1065
  end
1070
1066
 
1071
1067
  @emissions[key].annual_output_by_end_use[eu_key] = UnitConversions.convert(end_use.annual_output, end_use.annual_units, 'MBtu') * fuel_factor * fuel_units_mult
1072
- next unless include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
1068
+ next unless args[:include_timeseries_emissions] || args[:include_timeseries_emission_end_uses] || args[:include_timeseries_emission_fuels]
1073
1069
 
1074
1070
  fuel_to_mbtu = UnitConversions.convert(1.0, end_use.timeseries_units, 'MBtu')
1075
-
1076
- end_use.timeseries_output_by_system.each do |_sys_id, timeseries_output|
1077
- @emissions[key].timeseries_output_by_end_use[eu_key] = [0.0] * timeseries_output.size if @emissions[key].timeseries_output_by_end_use[eu_key].nil?
1078
- @emissions[key].timeseries_output_by_end_use[eu_key] = @emissions[key].timeseries_output_by_end_use[eu_key].zip(timeseries_output.map { |f| f * fuel_to_mbtu * fuel_factor * fuel_units_mult }).map { |x, y| x + y }
1079
- end
1071
+ @emissions[key].timeseries_output_by_end_use[eu_key] = end_use.timeseries_output_by_system.values.transpose.map(&:sum).map { |f| f * fuel_to_mbtu * fuel_factor * fuel_units_mult }
1080
1072
  end
1081
1073
 
1082
1074
  # Roll up end use emissions to fuel emissions
1083
1075
  @fuels.each do |fuel_type, _fuel|
1084
- @emissions[key].annual_output_by_fuel[fuel_type] = 0.0
1085
- @emissions[key].annual_output_by_end_use.keys.each do |eu_key|
1086
- next unless eu_key[0] == fuel_type
1087
- next if @emissions[key].annual_output_by_end_use[eu_key] == 0
1076
+ if fuel_type == FT::Elec
1077
+ emission_types = [TE::Total, TE::Net]
1078
+ else
1079
+ emission_types = [TE::Total]
1080
+ end
1081
+ emission_types.each do |emission_type|
1082
+ fuel_key = [fuel_type, emission_type]
1083
+ @emissions[key].annual_output_by_fuel[fuel_key] = 0.0
1084
+ @emissions[key].annual_output_by_end_use.keys.each do |eu_key|
1085
+ next unless eu_key[0] == fuel_type
1086
+ next if emission_type == TE::Total && @end_uses[eu_key].is_negative # Generation not included in total
1087
+ next if @emissions[key].annual_output_by_end_use[eu_key] == 0
1088
1088
 
1089
- @emissions[key].annual_output_by_fuel[fuel_type] += @emissions[key].annual_output_by_end_use[eu_key]
1089
+ @emissions[key].annual_output_by_fuel[fuel_key] += @emissions[key].annual_output_by_end_use[eu_key]
1090
1090
 
1091
- next unless include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
1091
+ next unless args[:include_timeseries_emissions] || args[:include_timeseries_emission_fuels]
1092
1092
 
1093
- @emissions[key].timeseries_output_by_fuel[fuel_type] = [0.0] * @emissions[key].timeseries_output_by_end_use[eu_key].size if @emissions[key].timeseries_output_by_fuel[fuel_type].nil?
1094
- @emissions[key].timeseries_output_by_fuel[fuel_type] = @emissions[key].timeseries_output_by_fuel[fuel_type].zip(@emissions[key].timeseries_output_by_end_use[eu_key]).map { |x, y| x + y }
1093
+ @emissions[key].timeseries_output_by_fuel[fuel_key] = [0.0] * @emissions[key].timeseries_output_by_end_use[eu_key].size if @emissions[key].timeseries_output_by_fuel[fuel_key].nil?
1094
+ @emissions[key].timeseries_output_by_fuel[fuel_key] = @emissions[key].timeseries_output_by_fuel[fuel_key].zip(@emissions[key].timeseries_output_by_end_use[eu_key]).map { |x, y| x + y }
1095
+ end
1095
1096
  end
1096
1097
  end
1097
1098
 
1098
- # Sum individual fuel results for total
1099
- @emissions[key].annual_output = @emissions[key].annual_output_by_fuel.values.sum()
1100
- next unless not @emissions[key].timeseries_output_by_fuel.empty?
1101
-
1102
- @emissions[key].timeseries_output = @emissions[key].timeseries_output_by_fuel.first[1]
1103
- @emissions[key].timeseries_output_by_fuel.each_with_index do |(_fuel, timeseries_output), i|
1104
- next if i == 0
1105
-
1106
- @emissions[key].timeseries_output = @emissions[key].timeseries_output.zip(timeseries_output).map { |x, y| x + y }
1099
+ # Sum individual fuel results for total/net
1100
+ total_keys = @emissions[key].annual_output_by_fuel.keys.select { |k| k[0] != FT::Elec || (k[0] == FT::Elec && k[1] == TE::Total) }
1101
+ net_keys = @emissions[key].annual_output_by_fuel.keys.select { |k| k[0] != FT::Elec || (k[0] == FT::Elec && k[1] == TE::Net) }
1102
+ @emissions[key].annual_output = @emissions[key].annual_output_by_fuel.select { |k, _v| total_keys.include? k }.values.sum()
1103
+ @emissions[key].net_annual_output = @emissions[key].annual_output_by_fuel.select { |k, _v| net_keys.include? k }.values.sum()
1104
+ if args[:include_timeseries_emissions]
1105
+ @emissions[key].timeseries_output = @emissions[key].timeseries_output_by_fuel.select { |k, _v| total_keys.include? k }.values.transpose.map(&:sum)
1106
+ @emissions[key].net_timeseries_output = @emissions[key].timeseries_output_by_fuel.select { |k, _v| net_keys.include? k }.values.transpose.map(&:sum)
1107
1107
  end
1108
1108
  end
1109
1109
  end
@@ -1137,8 +1137,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1137
1137
 
1138
1138
  # Check if simulation successful
1139
1139
  all_total = @fuels.values.map { |x| x.annual_output.to_f }.sum(0.0)
1140
- all_total += @ideal_system_loads.values.map { |x| x.annual_output.to_f }.sum(0.0)
1141
- if all_total == 0
1140
+ if (all_total == 0) && (@hpxml.total_fraction_cool_load_served + @hpxml.total_fraction_heat_load_served > 0)
1142
1141
  runner.registerError('Simulation unsuccessful.')
1143
1142
  return false
1144
1143
  elsif all_total.infinite?
@@ -1169,6 +1168,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1169
1168
  # Check sum of timeseries outputs match annual outputs
1170
1169
  { @totals => 'Total',
1171
1170
  @end_uses => 'End Use',
1171
+ @system_uses => 'System Use',
1172
1172
  @fuels => 'Fuel',
1173
1173
  @emissions => 'Emissions',
1174
1174
  @loads => 'Load',
@@ -1188,80 +1188,161 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1188
1188
  return true
1189
1189
  end
1190
1190
 
1191
- def report_runperiod_output_results(runner, outputs, output_format, annual_output_path, n_digits, generate_eri_outputs)
1191
+ def report_runperiod_output_results(runner, outputs, args, annual_output_path)
1192
+ # Set rounding precision for run period (e.g., annual) outputs.
1193
+ if args[:output_format] == 'msgpack'
1194
+ # No need to round; no file size penalty to storing full precision
1195
+ n_digits = 100
1196
+ else
1197
+ # Note: Make sure to round outputs with sufficient resolution for the worst case -- i.e., 1 day instead of a full year.
1198
+ 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))
1201
+ if sim_n_days <= 10 # 10 days or less; add two decimal places
1202
+ n_digits += 2
1203
+ elsif sim_n_days <= 100 # 100 days or less; add one decimal place
1204
+ n_digits += 1
1205
+ end
1206
+ end
1207
+
1192
1208
  line_break = nil
1193
1209
 
1194
1210
  results_out = []
1195
- @totals.each do |_energy_type, total_energy|
1196
- results_out << ["#{total_energy.name} (#{total_energy.annual_units})", total_energy.annual_output.to_f.round(n_digits)]
1211
+
1212
+ # Totals
1213
+ if args[:include_annual_total_consumptions]
1214
+ @totals.each do |_energy_type, total_energy|
1215
+ results_out << ["#{total_energy.name} (#{total_energy.annual_units})", total_energy.annual_output.to_f.round(n_digits)]
1216
+ end
1217
+ results_out << [line_break]
1197
1218
  end
1198
- results_out << [line_break]
1199
- @fuels.each do |fuel_type, fuel|
1200
- results_out << ["#{fuel.name} (#{fuel.annual_units})", fuel.annual_output.to_f.round(n_digits)]
1201
- if fuel_type == FT::Elec
1202
- results_out << ['Fuel Use: Electricity: Net (MBtu)', outputs[:elec_net_annual].round(n_digits)]
1219
+
1220
+ # Fuels
1221
+ if args[:include_annual_fuel_consumptions]
1222
+ @fuels.each do |fuel_type, fuel|
1223
+ results_out << ["#{fuel.name} (#{fuel.annual_units})", fuel.annual_output.to_f.round(n_digits)]
1224
+ if fuel_type == FT::Elec
1225
+ results_out << ['Fuel Use: Electricity: Net (MBtu)', outputs[:elec_net_annual].round(n_digits)]
1226
+ end
1203
1227
  end
1228
+ results_out << [line_break]
1204
1229
  end
1205
- results_out << [line_break]
1206
- @end_uses.each do |_key, end_use|
1207
- results_out << ["#{end_use.name} (#{end_use.annual_units})", end_use.annual_output.to_f.round(n_digits)]
1230
+
1231
+ # End uses
1232
+ if args[:include_annual_end_use_consumptions]
1233
+ @end_uses.each do |_key, end_use|
1234
+ results_out << ["#{end_use.name} (#{end_use.annual_units})", end_use.annual_output.to_f.round(n_digits)]
1235
+ end
1236
+ results_out << [line_break]
1208
1237
  end
1209
- if not @emissions.empty?
1238
+
1239
+ # System uses
1240
+ if args[:include_annual_system_use_consumptions]
1241
+ @system_uses.each do |_key, system_use|
1242
+ results_out << ["#{system_use.name} (#{system_use.annual_units})", system_use.annual_output.round(n_digits)]
1243
+ end
1210
1244
  results_out << [line_break]
1211
- @emissions.each do |_scenario_key, emission|
1212
- # Emissions total
1213
- results_out << ["#{emission.name}: Total (#{emission.annual_units})", emission.annual_output.to_f.round(2)]
1214
- # Emissions by fuel
1215
- emission.annual_output_by_fuel.each do |fuel, annual_output|
1216
- next if annual_output.to_f == 0
1217
-
1218
- results_out << ["#{emission.name}: #{fuel}: Total (#{emission.annual_units})", annual_output.to_f.round(2)]
1219
- # Emissions by end use
1220
- emission.annual_output_by_end_use.each do |key, eu_annual_output|
1221
- fuel_type, end_use_type = key
1222
- next unless fuel_type == fuel
1223
- next if eu_annual_output.to_f == 0
1224
-
1225
- results_out << ["#{emission.name}: #{fuel_type}: #{end_use_type} (#{emission.annual_units})", eu_annual_output.to_f.round(2)]
1245
+ end
1246
+
1247
+ # Total Emissions
1248
+ if args[:include_annual_emissions]
1249
+ if not @emissions.empty?
1250
+ @emissions.each do |_scenario_key, emission|
1251
+ results_out << ["#{emission.name}: Total (#{emission.annual_units})", emission.annual_output.to_f.round(n_digits - 1)]
1252
+ results_out << ["#{emission.name}: Net (#{emission.annual_units})", emission.net_annual_output.to_f.round(n_digits - 1)]
1253
+ end
1254
+ results_out << [line_break]
1255
+ end
1256
+ end
1257
+
1258
+ # Fuel Emissions
1259
+ if args[:include_annual_emission_fuels]
1260
+ if not @emissions.empty?
1261
+ @emissions.each do |_scenario_key, emission|
1262
+ emission.annual_output_by_fuel.keys.each do |fuel_key|
1263
+ fuel, emission_type = fuel_key
1264
+ results_out << ["#{emission.name}: #{fuel}: #{emission_type} (#{emission.annual_units})", emission.annual_output_by_fuel[fuel_key].to_f.round(n_digits - 1)]
1226
1265
  end
1227
1266
  end
1267
+ results_out << [line_break]
1228
1268
  end
1229
1269
  end
1230
- results_out << [line_break]
1231
- @loads.each do |_load_type, load|
1232
- results_out << ["#{load.name} (#{load.annual_units})", load.annual_output.to_f.round(n_digits)]
1270
+
1271
+ # End Use Emissions
1272
+ if args[:include_annual_emission_end_uses]
1273
+ if not @emissions.empty?
1274
+ @emissions.each do |_scenario_key, emission|
1275
+ @fuels.keys.each do |fuel|
1276
+ @end_uses.keys.each do |key|
1277
+ fuel_type, end_use_type = key
1278
+ next unless fuel_type == fuel
1279
+
1280
+ results_out << ["#{emission.name}: #{fuel_type}: #{end_use_type} (#{emission.annual_units})", emission.annual_output_by_end_use[key].to_f.round(n_digits - 1)]
1281
+ end
1282
+ end
1283
+ end
1284
+ results_out << [line_break]
1285
+ end
1233
1286
  end
1234
- results_out << [line_break]
1235
- @unmet_hours.each do |_load_type, unmet_hour|
1236
- results_out << ["#{unmet_hour.name} (#{unmet_hour.annual_units})", unmet_hour.annual_output.to_f.round(n_digits)]
1287
+
1288
+ # Loads
1289
+ if args[:include_annual_total_loads]
1290
+ @loads.each do |_load_type, load|
1291
+ results_out << ["#{load.name} (#{load.annual_units})", load.annual_output.to_f.round(n_digits)]
1292
+ end
1293
+ results_out << [line_break]
1237
1294
  end
1238
- results_out << [line_break]
1239
- @peak_fuels.each do |_key, peak_fuel|
1240
- results_out << ["#{peak_fuel.name} (#{peak_fuel.annual_units})", peak_fuel.annual_output.to_f.round(n_digits - 2)]
1295
+
1296
+ # Unmet hours
1297
+ if args[:include_annual_unmet_hours]
1298
+ @unmet_hours.each do |_load_type, unmet_hour|
1299
+ results_out << ["#{unmet_hour.name} (#{unmet_hour.annual_units})", unmet_hour.annual_output.to_f.round(n_digits)]
1300
+ end
1301
+ results_out << [line_break]
1241
1302
  end
1242
- results_out << [line_break]
1243
- @peak_loads.each do |_load_type, peak_load|
1244
- results_out << ["#{peak_load.name} (#{peak_load.annual_units})", peak_load.annual_output.to_f.round(n_digits)]
1303
+
1304
+ # Peak fuels
1305
+ if args[:include_annual_peak_fuels]
1306
+ @peak_fuels.each do |_key, peak_fuel|
1307
+ results_out << ["#{peak_fuel.name} (#{peak_fuel.annual_units})", peak_fuel.annual_output.to_f.round(n_digits - 2)]
1308
+ end
1309
+ results_out << [line_break]
1245
1310
  end
1246
- if @component_loads.values.map { |load| load.annual_output.to_f }.sum != 0 # Skip if component loads not calculated
1311
+
1312
+ # Peak loads
1313
+ if args[:include_annual_peak_loads]
1314
+ @peak_loads.each do |_load_type, peak_load|
1315
+ results_out << ["#{peak_load.name} (#{peak_load.annual_units})", peak_load.annual_output.to_f.round(n_digits)]
1316
+ end
1247
1317
  results_out << [line_break]
1248
- @component_loads.each do |_load_type, load|
1249
- results_out << ["#{load.name} (#{load.annual_units})", load.annual_output.to_f.round(n_digits)]
1318
+ end
1319
+
1320
+ # Component loads
1321
+ if args[:include_annual_component_loads]
1322
+ if @component_loads.values.map { |load| load.annual_output.to_f }.sum != 0 # Skip if component loads not calculated
1323
+ @component_loads.each do |_load_type, load|
1324
+ results_out << ["#{load.name} (#{load.annual_units})", load.annual_output.to_f.round(n_digits)]
1325
+ end
1326
+ results_out << [line_break]
1250
1327
  end
1251
1328
  end
1252
- results_out << [line_break]
1253
- @hot_water_uses.each do |_hot_water_type, hot_water|
1254
- results_out << ["#{hot_water.name} (#{hot_water.annual_units})", hot_water.annual_output.to_f.round(n_digits - 2)]
1329
+
1330
+ # Hot water uses
1331
+ if args[:include_annual_hot_water_uses]
1332
+ @hot_water_uses.each do |_hot_water_type, hot_water|
1333
+ results_out << ["#{hot_water.name} (#{hot_water.annual_units})", hot_water.annual_output.to_f.round(n_digits - 2)]
1334
+ end
1335
+ results_out << [line_break]
1255
1336
  end
1256
1337
 
1257
- results_out = append_sizing_results(results_out, line_break)
1258
- if generate_eri_outputs
1259
- results_out = append_eri_results(results_out, line_break)
1338
+ # Sizing data
1339
+ if args[:include_annual_hvac_summary]
1340
+ results_out = append_sizing_results(results_out, line_break)
1260
1341
  end
1261
1342
 
1262
- if ['csv'].include? output_format
1343
+ if ['csv'].include? args[:output_format]
1263
1344
  CSV.open(annual_output_path, 'wb') { |csv| results_out.to_a.each { |elem| csv << elem } }
1264
- elsif ['json', 'msgpack'].include? output_format
1345
+ elsif ['json', 'msgpack'].include? args[:output_format]
1265
1346
  h = {}
1266
1347
  results_out.each do |out|
1267
1348
  next if out == [line_break]
@@ -1271,10 +1352,10 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1271
1352
  h[grp][name.strip] = out[1]
1272
1353
  end
1273
1354
 
1274
- if output_format == 'json'
1355
+ if args[:output_format] == 'json'
1275
1356
  require 'json'
1276
1357
  File.open(annual_output_path, 'w') { |json| json.write(JSON.pretty_generate(h)) }
1277
- elsif output_format == 'msgpack'
1358
+ elsif args[:output_format] == 'msgpack'
1278
1359
  File.open(annual_output_path, 'w') { |json| h.to_msgpack(json) }
1279
1360
  end
1280
1361
  end
@@ -1290,10 +1371,6 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1290
1371
  end
1291
1372
  end
1292
1373
 
1293
- def get_runner_output_name(name, annual_units)
1294
- return "#{name} #{annual_units}"
1295
- end
1296
-
1297
1374
  def append_sizing_results(results_out, line_break)
1298
1375
  # Summary HVAC capacities
1299
1376
  htg_cap, clg_cap, hp_backup_cap = 0.0, 0.0, 0.0
@@ -1317,15 +1394,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1317
1394
  end
1318
1395
  end
1319
1396
  end
1320
- results_out << [line_break]
1321
1397
  results_out << ['HVAC Capacity: Heating (Btu/h)', htg_cap.round(1)]
1322
1398
  results_out << ['HVAC Capacity: Cooling (Btu/h)', clg_cap.round(1)]
1323
1399
  results_out << ['HVAC Capacity: Heat Pump Backup (Btu/h)', hp_backup_cap.round(1)]
1324
1400
 
1325
1401
  # HVAC design temperatures
1326
1402
  results_out << [line_break]
1327
- results_out << ['HVAC Design Temperature: Heating (F)', @hpxml.hvac_plant.temp_heating.round(2)]
1328
- results_out << ['HVAC Design Temperature: Cooling (F)', @hpxml.hvac_plant.temp_cooling.round(2)]
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)]
1329
1405
 
1330
1406
  # HVAC design loads
1331
1407
  results_out << [line_break]
@@ -1360,342 +1436,56 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1360
1436
  return results_out
1361
1437
  end
1362
1438
 
1363
- def append_eri_results(results_out, line_break)
1364
- def ordered_values(hash, sys_ids)
1365
- vals = []
1366
- sys_ids.each do |sys_id|
1367
- if not hash[sys_id].nil?
1368
- if hash[sys_id].is_a? Float
1369
- vals << hash[sys_id].round(3)
1370
- else
1371
- vals << hash[sys_id]
1372
- end
1373
- else
1374
- vals << 0.0
1375
- end
1376
- end
1377
- return if vals.empty?
1378
-
1379
- return vals.join(',')
1380
- end
1381
-
1382
- def get_eec_value_numerator(unit)
1383
- if ['HSPF', 'HSPF2', 'SEER', 'SEER2', 'EER', 'CEER'].include? unit
1384
- return 3.413
1385
- elsif ['AFUE', 'COP', 'Percent', 'EF'].include? unit
1386
- return 1.0
1387
- end
1388
- end
1389
-
1390
- def get_ids(ids, seed_id_map = {})
1391
- new_ids = ids.map { |id| seed_id_map[id].nil? ? id : seed_id_map[id] }
1392
- return if new_ids.empty?
1393
-
1394
- return new_ids.join(',')
1395
- end
1396
-
1397
- # Retrieve info from HPXML object
1398
- htg_ids, clg_ids, dhw_ids, prehtg_ids, preclg_ids = [], [], [], [], []
1399
- htg_eecs, clg_eecs, dhw_eecs, prehtg_eecs, preclg_eecs = {}, {}, {}, {}, {}
1400
- htg_fuels, clg_fuels, dhw_fuels, prehtg_fuels, preclg_fuels = {}, {}, {}, {}, {}
1401
- htg_seed_id_map, clg_seed_id_map = {}, {}
1402
- @hpxml.heating_systems.each do |htg_system|
1403
- next unless htg_system.fraction_heat_load_served > 0
1404
-
1405
- htg_ids << htg_system.id
1406
- htg_seed_id_map[htg_system.id] = htg_system.htg_seed_id
1407
- htg_fuels[htg_system.id] = htg_system.heating_system_fuel
1408
- if not htg_system.heating_efficiency_afue.nil?
1409
- htg_eecs[htg_system.id] = get_eec_value_numerator('AFUE') / htg_system.heating_efficiency_afue
1410
- elsif not htg_system.heating_efficiency_percent.nil?
1411
- htg_eecs[htg_system.id] = get_eec_value_numerator('Percent') / htg_system.heating_efficiency_percent
1412
- end
1413
- end
1414
- @hpxml.cooling_systems.each do |clg_system|
1415
- if clg_system.has_integrated_heating && clg_system.integrated_heating_system_fraction_heat_load_served > 0
1416
- # Cooling system w/ integrated heating (e.g., Room AC w/ electric resistance heating)
1417
- htg_ids << clg_system.id
1418
- htg_seed_id_map[clg_system.id] = clg_system.htg_seed_id
1419
- htg_fuels[clg_system.id] = clg_system.integrated_heating_system_fuel
1420
- htg_eecs[clg_system.id] = get_eec_value_numerator('Percent') / clg_system.integrated_heating_system_efficiency_percent
1421
- end
1422
-
1423
- next unless clg_system.fraction_cool_load_served > 0
1424
-
1425
- clg_ids << clg_system.id
1426
- clg_seed_id_map[clg_system.id] = clg_system.clg_seed_id
1427
- clg_fuels[clg_system.id] = clg_system.cooling_system_fuel
1428
- if not clg_system.cooling_efficiency_seer.nil?
1429
- clg_eecs[clg_system.id] = get_eec_value_numerator('SEER') / clg_system.cooling_efficiency_seer
1430
- elsif not clg_system.cooling_efficiency_seer2.nil?
1431
- clg_eecs[clg_system.id] = get_eec_value_numerator('SEER2') / clg_system.cooling_efficiency_seer2
1432
- elsif not clg_system.cooling_efficiency_eer.nil?
1433
- clg_eecs[clg_system.id] = get_eec_value_numerator('EER') / clg_system.cooling_efficiency_eer
1434
- elsif not clg_system.cooling_efficiency_ceer.nil?
1435
- clg_eecs[clg_system.id] = get_eec_value_numerator('CEER') / clg_system.cooling_efficiency_ceer
1436
- end
1437
- if clg_system.cooling_system_type == HPXML::HVACTypeEvaporativeCooler
1438
- clg_eecs[clg_system.id] = get_eec_value_numerator('SEER') / 15.0 # Arbitrary
1439
- end
1440
- end
1441
- @hpxml.heat_pumps.each do |heat_pump|
1442
- if heat_pump.fraction_heat_load_served > 0
1443
- htg_ids << heat_pump.id
1444
- htg_seed_id_map[heat_pump.id] = heat_pump.htg_seed_id
1445
- htg_fuels[heat_pump.id] = heat_pump.heat_pump_fuel
1446
- if not heat_pump.heating_efficiency_hspf.nil?
1447
- htg_eecs[heat_pump.id] = get_eec_value_numerator('HSPF') / heat_pump.heating_efficiency_hspf
1448
- elsif not heat_pump.heating_efficiency_hspf2.nil?
1449
- htg_eecs[heat_pump.id] = get_eec_value_numerator('HSPF2') / heat_pump.heating_efficiency_hspf2
1450
- elsif not heat_pump.heating_efficiency_cop.nil?
1451
- htg_eecs[heat_pump.id] = get_eec_value_numerator('COP') / heat_pump.heating_efficiency_cop
1452
- end
1453
- end
1454
- next unless heat_pump.fraction_cool_load_served > 0
1455
-
1456
- clg_ids << heat_pump.id
1457
- clg_seed_id_map[heat_pump.id] = heat_pump.clg_seed_id
1458
- clg_fuels[heat_pump.id] = heat_pump.heat_pump_fuel
1459
- if not heat_pump.cooling_efficiency_seer.nil?
1460
- clg_eecs[heat_pump.id] = get_eec_value_numerator('SEER') / heat_pump.cooling_efficiency_seer
1461
- elsif not heat_pump.cooling_efficiency_seer2.nil?
1462
- clg_eecs[heat_pump.id] = get_eec_value_numerator('SEER2') / heat_pump.cooling_efficiency_seer2
1463
- elsif not heat_pump.cooling_efficiency_eer.nil?
1464
- clg_eecs[heat_pump.id] = get_eec_value_numerator('EER') / heat_pump.cooling_efficiency_eer
1465
- end
1466
- end
1467
- @hpxml.water_heating_systems.each do |dhw_system|
1468
- dhw_ids << dhw_system.id
1469
- ef_or_uef = nil
1470
- ef_or_uef = dhw_system.energy_factor unless dhw_system.energy_factor.nil?
1471
- ef_or_uef = dhw_system.uniform_energy_factor unless dhw_system.uniform_energy_factor.nil?
1472
- if ef_or_uef.nil?
1473
- # Get assumed EF for combi system
1474
- @model.getWaterHeaterMixeds.each do |wh|
1475
- dhw_id = wh.additionalProperties.getFeatureAsString('HPXML_ID')
1476
- next unless (dhw_id.is_initialized && dhw_id.get == dhw_system.id)
1477
-
1478
- ef_or_uef = wh.additionalProperties.getFeatureAsDouble('EnergyFactor').get
1479
- end
1480
- end
1481
- value_adj = 1.0
1482
- value_adj = dhw_system.performance_adjustment if dhw_system.water_heater_type == HPXML::WaterHeaterTypeTankless
1483
- if (not ef_or_uef.nil?) && (not value_adj.nil?)
1484
- dhw_eecs[dhw_system.id] = get_eec_value_numerator('EF') / (Float(ef_or_uef) * Float(value_adj))
1485
- end
1486
- if [HPXML::WaterHeaterTypeCombiTankless, HPXML::WaterHeaterTypeCombiStorage].include? dhw_system.water_heater_type
1487
- dhw_fuels[dhw_system.id] = dhw_system.related_hvac_system.heating_system_fuel
1488
- else
1489
- dhw_fuels[dhw_system.id] = dhw_system.fuel_type
1490
- end
1491
- end
1492
- @hpxml.ventilation_fans.each do |vent_fan|
1493
- next unless vent_fan.used_for_whole_building_ventilation
1494
- next if vent_fan.is_cfis_supplemental_fan?
1495
-
1496
- if not vent_fan.preheating_fuel.nil?
1497
- prehtg_ids << vent_fan.id
1498
- prehtg_fuels[vent_fan.id] = vent_fan.preheating_fuel
1499
- prehtg_eecs[vent_fan.id] = get_eec_value_numerator('COP') / vent_fan.preheating_efficiency_cop
1500
- end
1501
- next unless not vent_fan.precooling_fuel.nil?
1502
-
1503
- preclg_ids << vent_fan.id
1504
- preclg_fuels[vent_fan.id] = vent_fan.precooling_fuel
1505
- preclg_eecs[vent_fan.id] = get_eec_value_numerator('COP') / vent_fan.precooling_efficiency_cop
1506
- end
1507
-
1508
- # Apportion ERI Reference loads to systems
1509
- (@hpxml.heating_systems + @hpxml.heat_pumps).each do |htg_system|
1510
- next unless htg_ids.include? htg_system.id
1511
-
1512
- @loads[LT::Heating].annual_output_by_system[htg_system.id] = htg_system.fraction_heat_load_served * @loads[LT::Heating].annual_output
1513
- end
1514
- (@hpxml.cooling_systems + @hpxml.heat_pumps).each do |clg_system|
1515
- if clg_ids.include? clg_system.id
1516
- @loads[LT::Cooling].annual_output_by_system[clg_system.id] = clg_system.fraction_cool_load_served * @loads[LT::Cooling].annual_output
1517
- end
1518
- next unless (clg_system.is_a? HPXML::CoolingSystem) && clg_system.has_integrated_heating # Cooling system w/ integrated heating (e.g., Room AC w/ electric resistance heating)
1519
-
1520
- if htg_ids.include? clg_system.id
1521
- @loads[LT::Heating].annual_output_by_system[clg_system.id] = clg_system.integrated_heating_system_fraction_heat_load_served * @loads[LT::Heating].annual_output
1522
- end
1523
- end
1524
-
1525
- # Handle dual-fuel heat pumps
1526
- @hpxml.heat_pumps.each do |heat_pump|
1527
- next unless heat_pump.is_dual_fuel
1528
-
1529
- # Create separate dual fuel heat pump backup system
1530
- dfhp_backup_id = heat_pump.id + '_DFHPBackup'
1531
- htg_ids << dfhp_backup_id
1532
- htg_seed_id_map[dfhp_backup_id] = heat_pump.htg_seed_id + '_DFHPBackup'
1533
- htg_fuels[dfhp_backup_id] = heat_pump.backup_heating_fuel
1534
- if not heat_pump.backup_heating_efficiency_afue.nil?
1535
- htg_eecs[dfhp_backup_id] = get_eec_value_numerator('AFUE') / heat_pump.backup_heating_efficiency_afue
1536
- elsif not heat_pump.backup_heating_efficiency_percent.nil?
1537
- htg_eecs[dfhp_backup_id] = get_eec_value_numerator('Percent') / heat_pump.backup_heating_efficiency_percent
1538
- end
1539
-
1540
- # Apportion heating load for the two systems
1541
- primary_load, backup_load = nil
1542
- @object_variables_by_key[[LT, LT::Heating]].each do |vals|
1543
- sys_id, key_name, var_name = vals
1544
- if sys_id == heat_pump.id
1545
- primary_load = get_report_variable_data_annual([key_name], [var_name])
1546
- elsif sys_id == heat_pump.id + '_DFHPBackup'
1547
- backup_load = get_report_variable_data_annual([key_name], [var_name])
1548
- end
1549
- end
1550
- fail 'Could not obtain DFHP loads.' if primary_load.nil? || backup_load.nil?
1551
-
1552
- total_load = @loads[LT::Heating].annual_output_by_system[heat_pump.id]
1553
- backup_ratio = backup_load / (primary_load + backup_load)
1554
- @loads[LT::Heating].annual_output_by_system[dfhp_backup_id] = total_load * backup_ratio
1555
- @loads[LT::Heating].annual_output_by_system[heat_pump.id] = total_load * (1.0 - backup_ratio)
1556
- end
1557
-
1558
- # Collect final ERI Reference loads by system
1559
- htg_loads, clg_loads, dhw_loads = {}, {}, {}
1560
- @loads.each do |load_type, load|
1561
- if load_type == LT::Heating
1562
- htg_loads = load.annual_output_by_system
1563
- elsif load_type == LT::Cooling
1564
- clg_loads = load.annual_output_by_system
1565
- elsif load_type == LT::HotWaterDelivered
1566
- dhw_loads = load.annual_output_by_system
1567
- end
1568
- end
1569
-
1570
- # Collect energy consumption (EC) by system
1571
- htg_ecs, clg_ecs, dhw_ecs, prehtg_ecs, preclg_ecs = {}, {}, {}, {}, {}
1572
- eut_map = { EUT::Heating => htg_ecs,
1573
- EUT::HeatingHeatPumpBackup => htg_ecs,
1574
- EUT::HeatingFanPump => htg_ecs,
1575
- EUT::Cooling => clg_ecs,
1576
- EUT::CoolingFanPump => clg_ecs,
1577
- EUT::HotWater => dhw_ecs,
1578
- EUT::HotWaterRecircPump => dhw_ecs,
1579
- EUT::HotWaterSolarThermalPump => dhw_ecs,
1580
- EUT::MechVentPreheat => prehtg_ecs,
1581
- EUT::MechVentPrecool => preclg_ecs }
1582
- @end_uses.each do |key, end_use|
1583
- _fuel_type, end_use_type = key
1584
- ec_obj = eut_map[end_use_type]
1585
- next if ec_obj.nil?
1586
-
1587
- end_use.annual_output_by_system.each do |sys_id, val|
1588
- ec_obj[sys_id] = 0.0 if ec_obj[sys_id].nil?
1589
- ec_obj[sys_id] += val
1590
- end
1591
- end
1592
-
1593
- results_out << [line_break]
1594
-
1595
- # Building
1596
- results_out << ['ERI: Building: CFA', @hpxml.building_construction.conditioned_floor_area]
1597
- results_out << ['ERI: Building: NumBedrooms', @hpxml.building_construction.number_of_bedrooms]
1598
- results_out << ['ERI: Building: NumStories', @hpxml.building_construction.number_of_conditioned_floors_above_grade]
1599
- results_out << ['ERI: Building: Type', @hpxml.building_construction.residential_facility_type]
1600
-
1601
- # Heating
1602
- results_out << ['ERI: Heating: ID', get_ids(htg_ids, htg_seed_id_map)]
1603
- results_out << ['ERI: Heating: FuelType', ordered_values(htg_fuels, htg_ids)]
1604
- results_out << ['ERI: Heating: EC', ordered_values(htg_ecs, htg_ids)]
1605
- results_out << ['ERI: Heating: EEC', ordered_values(htg_eecs, htg_ids)]
1606
- results_out << ['ERI: Heating: Load', ordered_values(htg_loads, htg_ids)]
1607
-
1608
- # Cooling
1609
- results_out << ['ERI: Cooling: ID', get_ids(clg_ids, clg_seed_id_map)]
1610
- results_out << ['ERI: Cooling: FuelType', ordered_values(clg_fuels, clg_ids)]
1611
- results_out << ['ERI: Cooling: EC', ordered_values(clg_ecs, clg_ids)]
1612
- results_out << ['ERI: Cooling: EEC', ordered_values(clg_eecs, clg_ids)]
1613
- results_out << ['ERI: Cooling: Load', ordered_values(clg_loads, clg_ids)]
1614
-
1615
- # Hot Water
1616
- results_out << ['ERI: Hot Water: ID', get_ids(dhw_ids)]
1617
- results_out << ['ERI: Hot Water: FuelType', ordered_values(dhw_fuels, dhw_ids)]
1618
- results_out << ['ERI: Hot Water: EC', ordered_values(dhw_ecs, dhw_ids)]
1619
- results_out << ['ERI: Hot Water: EEC', ordered_values(dhw_eecs, dhw_ids)]
1620
- results_out << ['ERI: Hot Water: Load', ordered_values(dhw_loads, dhw_ids)]
1621
-
1622
- # Mech Vent Preheat
1623
- results_out << ['ERI: Mech Vent Preheating: ID', get_ids(prehtg_ids)]
1624
- results_out << ['ERI: Mech Vent Preheating: FuelType', ordered_values(prehtg_fuels, prehtg_ids)]
1625
- results_out << ['ERI: Mech Vent Preheating: EC', ordered_values(prehtg_ecs, prehtg_ids)]
1626
- results_out << ['ERI: Mech Vent Preheating: EEC', ordered_values(prehtg_eecs, prehtg_ids)]
1627
-
1628
- # Mech Vent Precool
1629
- results_out << ['ERI: Mech Vent Precooling: ID', get_ids(preclg_ids)]
1630
- results_out << ['ERI: Mech Vent Precooling: FuelType', ordered_values(preclg_fuels, preclg_ids)]
1631
- results_out << ['ERI: Mech Vent Precooling: EC', ordered_values(preclg_ecs, preclg_ids)]
1632
- results_out << ['ERI: Mech Vent Precooling: EEC', ordered_values(preclg_eecs, preclg_ids)]
1633
-
1634
- return results_out
1635
- end
1636
-
1637
- def report_timeseries_output_results(runner, outputs, output_format,
1638
- timeseries_output_path,
1639
- timeseries_frequency,
1640
- include_timeseries_total_consumptions,
1641
- include_timeseries_fuel_consumptions,
1642
- include_timeseries_end_use_consumptions,
1643
- include_timeseries_emissions,
1644
- include_timeseries_emission_fuels,
1645
- include_timeseries_emission_end_uses,
1646
- include_timeseries_hot_water_uses,
1647
- include_timeseries_total_loads,
1648
- include_timeseries_component_loads,
1649
- include_timeseries_unmet_hours,
1650
- include_timeseries_zone_temperatures,
1651
- include_timeseries_airflows,
1652
- include_timeseries_weather,
1653
- add_dst_column,
1654
- add_utc_column,
1655
- timestamps_dst,
1656
- timestamps_utc,
1657
- use_dview_format)
1439
+ def report_timeseries_output_results(runner, outputs, timeseries_output_path, args, timestamps_dst, timestamps_utc)
1658
1440
  return if @timestamps.nil?
1659
1441
 
1660
- if not ['timestep', 'hourly', 'daily', 'monthly'].include? timeseries_frequency
1661
- fail "Unexpected timeseries_frequency: #{timeseries_frequency}."
1442
+ if not ['timestep', 'hourly', 'daily', 'monthly'].include? args[:timeseries_frequency]
1443
+ fail "Unexpected timeseries_frequency: #{args[:timeseries_frequency]}."
1662
1444
  end
1663
1445
 
1664
- # Set rounding precision for timeseries (e.g., hourly) outputs.
1665
- # Note: Make sure to round outputs with sufficient resolution for the worst case -- i.e., 1 minute date instead of hourly data.
1666
- n_digits = 2 # Default for hourly (or longer) data
1667
- if timeseries_frequency == 'timestep'
1668
- if @hpxml.header.timestep <= 2 # 2-minute timesteps or shorter; add two decimal places
1669
- n_digits += 2
1670
- elsif @hpxml.header.timestep <= 15 # 15-minute timesteps or shorter; add one decimal place
1671
- n_digits += 1
1446
+ if args[:output_format] == 'msgpack'
1447
+ # No need to round; no file size penalty to storing full precision
1448
+ n_digits = 100
1449
+ elsif not args[:timeseries_num_decimal_places].nil?
1450
+ n_digits = args[:timeseries_num_decimal_places]
1451
+ else
1452
+ # Set rounding precision for timeseries (e.g., hourly) outputs.
1453
+ # Note: Make sure to round outputs with sufficient resolution for the worst case -- i.e., 1 minute date instead of hourly data.
1454
+ n_digits = 3 # Default for hourly (or longer) data
1455
+ if args[:timeseries_frequency] == 'timestep'
1456
+ if @hpxml.header.timestep <= 2 # 2-minute timesteps or shorter; add two decimal places
1457
+ n_digits += 2
1458
+ elsif @hpxml.header.timestep <= 15 # 15-minute timesteps or shorter; add one decimal place
1459
+ n_digits += 1
1460
+ end
1672
1461
  end
1673
1462
  end
1674
1463
 
1675
1464
  # Initial output data w/ Time column(s)
1676
1465
  data = ['Time', nil] + @timestamps
1677
- if add_dst_column
1466
+ if args[:add_timeseries_dst_column]
1678
1467
  timestamps2 = [['TimeDST', nil] + timestamps_dst]
1679
1468
  else
1680
1469
  timestamps2 = []
1681
1470
  end
1682
- if add_utc_column
1471
+ if args[:add_timeseries_utc_column]
1683
1472
  timestamps3 = [['TimeUTC', nil] + timestamps_utc]
1684
1473
  else
1685
1474
  timestamps3 = []
1686
1475
  end
1687
1476
 
1688
- if include_timeseries_total_consumptions
1477
+ if args[:include_timeseries_total_consumptions]
1689
1478
  total_energy_data = []
1690
1479
  [TE::Total, TE::Net].each do |energy_type|
1691
1480
  next if (energy_type == TE::Net) && (outputs[:elec_prod_timeseries].sum(0.0) == 0)
1481
+ next if @totals[energy_type].timeseries_output.empty?
1692
1482
 
1693
1483
  total_energy_data << [@totals[energy_type].name, @totals[energy_type].timeseries_units] + @totals[energy_type].timeseries_output.map { |v| v.round(n_digits) }
1694
1484
  end
1695
1485
  else
1696
1486
  total_energy_data = []
1697
1487
  end
1698
- if include_timeseries_fuel_consumptions
1488
+ if args[:include_timeseries_fuel_consumptions]
1699
1489
  fuel_data = @fuels.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) } }
1700
1490
 
1701
1491
  # Also add Net Electricity
@@ -1705,77 +1495,84 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1705
1495
  else
1706
1496
  fuel_data = []
1707
1497
  end
1708
- if include_timeseries_end_use_consumptions
1498
+ if args[:include_timeseries_end_use_consumptions]
1709
1499
  end_use_data = @end_uses.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) } }
1710
1500
  else
1711
1501
  end_use_data = []
1712
1502
  end
1713
- if include_timeseries_emissions
1503
+ if args[:include_timeseries_system_use_consumptions]
1504
+ system_use_data = @system_uses.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) } }
1505
+ else
1506
+ system_use_data = []
1507
+ end
1508
+ if args[:include_timeseries_emissions]
1714
1509
  emissions_data = []
1715
1510
  @emissions.values.each do |emission|
1716
1511
  next if emission.timeseries_output.sum(0.0) == 0
1717
1512
 
1718
- emissions_data << ["#{emission.name}: Total", emission.timeseries_units] + emission.timeseries_output.map { |v| v.round(5) }
1513
+ emissions_data << ["#{emission.name}: Total", emission.timeseries_units] + emission.timeseries_output.map { |v| v.round(n_digits + 2) }
1514
+ emissions_data << ["#{emission.name}: Net", emission.timeseries_units] + emission.net_timeseries_output.map { |v| v.round(n_digits + 2) }
1719
1515
  end
1720
1516
  else
1721
1517
  emissions_data = []
1722
1518
  end
1723
- if include_timeseries_emission_fuels
1519
+ if args[:include_timeseries_emission_fuels]
1724
1520
  emission_fuel_data = []
1725
1521
  @emissions.values.each do |emission|
1726
- emission.timeseries_output_by_fuel.each do |fuel, timeseries_output|
1522
+ emission.timeseries_output_by_fuel.each do |fuel_key, timeseries_output|
1523
+ fuel, emission_type = fuel_key
1727
1524
  next if timeseries_output.sum(0.0) == 0
1728
1525
 
1729
- emission_fuel_data << ["#{emission.name}: #{fuel}: Total", emission.timeseries_units] + timeseries_output.map { |v| v.round(5) }
1526
+ emission_fuel_data << ["#{emission.name}: #{fuel}: #{emission_type}", emission.timeseries_units] + timeseries_output.map { |v| v.round(n_digits + 2) }
1730
1527
  end
1731
1528
  end
1732
1529
  else
1733
1530
  emission_fuel_data = []
1734
1531
  end
1735
- if include_timeseries_emission_end_uses
1532
+ if args[:include_timeseries_emission_end_uses]
1736
1533
  emission_end_use_data = []
1737
1534
  @emissions.values.each do |emission|
1738
1535
  emission.timeseries_output_by_end_use.each do |key, timeseries_output|
1739
1536
  next if timeseries_output.sum(0.0) == 0
1740
1537
 
1741
1538
  fuel_type, end_use_type = key
1742
- emission_end_use_data << ["#{emission.name}: #{fuel_type}: #{end_use_type}", emission.timeseries_units] + timeseries_output.map { |v| v.round(5) }
1539
+ emission_end_use_data << ["#{emission.name}: #{fuel_type}: #{end_use_type}", emission.timeseries_units] + timeseries_output.map { |v| v.round(n_digits + 2) }
1743
1540
  end
1744
1541
  end
1745
1542
  else
1746
1543
  emission_end_use_data = []
1747
1544
  end
1748
- if include_timeseries_hot_water_uses
1545
+ if args[:include_timeseries_hot_water_uses]
1749
1546
  hot_water_use_data = @hot_water_uses.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) } }
1750
1547
  else
1751
1548
  hot_water_use_data = []
1752
1549
  end
1753
- if include_timeseries_total_loads
1550
+ if args[:include_timeseries_total_loads]
1754
1551
  total_loads_data = @loads.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) } }
1755
1552
  else
1756
1553
  total_loads_data = {}
1757
1554
  end
1758
- if include_timeseries_component_loads
1555
+ if args[:include_timeseries_component_loads]
1759
1556
  comp_loads_data = @component_loads.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) } }
1760
1557
  else
1761
1558
  comp_loads_data = []
1762
1559
  end
1763
- if include_timeseries_unmet_hours
1560
+ if args[:include_timeseries_unmet_hours]
1764
1561
  unmet_hours_data = @unmet_hours.values.map { |x| [x.name, x.timeseries_units] + x.timeseries_output.map { |v| v.round(n_digits) } }
1765
1562
  else
1766
1563
  unmet_hours_data = []
1767
1564
  end
1768
- if include_timeseries_zone_temperatures
1565
+ if args[:include_timeseries_zone_temperatures]
1769
1566
  zone_temps_data = @zone_temps.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) } }
1770
1567
  else
1771
1568
  zone_temps_data = []
1772
1569
  end
1773
- if include_timeseries_airflows
1570
+ if args[:include_timeseries_airflows]
1774
1571
  airflows_data = @airflows.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) } }
1775
1572
  else
1776
1573
  airflows_data = []
1777
1574
  end
1778
- if include_timeseries_weather
1575
+ if args[:include_timeseries_weather]
1779
1576
  weather_data = @weather.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) } }
1780
1577
  else
1781
1578
  weather_data = []
@@ -1788,15 +1585,15 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1788
1585
  output_variables_data = []
1789
1586
  end
1790
1587
 
1791
- return if (total_energy_data.size + fuel_data.size + end_use_data.size + emissions_data.size + emission_fuel_data.size +
1588
+ return if (total_energy_data.size + fuel_data.size + end_use_data.size + system_use_data.size + emissions_data.size + emission_fuel_data.size +
1792
1589
  emission_end_use_data.size + hot_water_use_data.size + total_loads_data.size + comp_loads_data.size + unmet_hours_data.size +
1793
1590
  zone_temps_data.size + airflows_data.size + weather_data.size + output_variables_data.size) == 0
1794
1591
 
1795
1592
  fail 'Unable to obtain timestamps.' if @timestamps.empty?
1796
1593
 
1797
- if ['csv'].include? output_format
1594
+ if ['csv'].include? args[:output_format]
1798
1595
  # Assemble data
1799
- data = data.zip(*timestamps2, *timestamps3, *total_energy_data, *fuel_data, *end_use_data, *emissions_data,
1596
+ data = data.zip(*timestamps2, *timestamps3, *total_energy_data, *fuel_data, *end_use_data, *system_use_data, *emissions_data,
1800
1597
  *emission_fuel_data, *emission_end_use_data, *hot_water_use_data, *total_loads_data, *comp_loads_data,
1801
1598
  *unmet_hours_data, *zone_temps_data, *airflows_data, *weather_data, *output_variables_data)
1802
1599
 
@@ -1809,7 +1606,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1809
1606
  fail "Inconsistent number of array elements: #{n_elements.uniq}."
1810
1607
  end
1811
1608
 
1812
- if use_dview_format
1609
+ if args[:use_dview_format]
1813
1610
  # Remove Time column(s)
1814
1611
  while data[0][0].include? 'Time'
1815
1612
  data = data.map { |a| a[1..-1] }
@@ -1819,13 +1616,13 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1819
1616
  year = @hpxml.header.sim_calendar_year
1820
1617
  start_day = Schedule.get_day_num_from_month_day(year, @hpxml.header.sim_begin_month, @hpxml.header.sim_begin_day)
1821
1618
  start_hr = (start_day - 1) * 24
1822
- if timeseries_frequency == 'timestep'
1619
+ if args[:timeseries_frequency] == 'timestep'
1823
1620
  interval_hrs = @hpxml.header.timestep / 60.0
1824
- elsif timeseries_frequency == 'hourly'
1621
+ elsif args[:timeseries_frequency] == 'hourly'
1825
1622
  interval_hrs = 1.0
1826
- elsif timeseries_frequency == 'daily'
1623
+ elsif args[:timeseries_frequency] == 'daily'
1827
1624
  interval_hrs = 24.0
1828
- elsif timeseries_frequency == 'monthly'
1625
+ elsif args[:timeseries_frequency] == 'monthly'
1829
1626
  interval_hrs = Constants.NumDaysInYear(year) * 24.0 / 12
1830
1627
  end
1831
1628
  header_data = [['wxDVFileHeaderVer.1'],
@@ -1837,9 +1634,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1837
1634
  data.delete_at(0) # Remove series name, added to header data above
1838
1635
 
1839
1636
  # Apply daylight savings
1840
- if timeseries_frequency == 'timestep' || timeseries_frequency == 'hourly'
1637
+ if args[:timeseries_frequency] == 'timestep' || args[:timeseries_frequency] == 'hourly'
1841
1638
  if @hpxml.header.dst_enabled
1842
- dst_start_ix, dst_end_ix = OutputMethods.get_dst_start_end_indexes(@timestamps, timestamps_dst)
1639
+ dst_start_ix, dst_end_ix = get_dst_start_end_indexes(@timestamps, timestamps_dst)
1843
1640
  dst_end_ix.downto(dst_start_ix + 1) do |i|
1844
1641
  data[i + 1] = data[i]
1845
1642
  end
@@ -1851,14 +1648,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1851
1648
 
1852
1649
  # Write file
1853
1650
  CSV.open(timeseries_output_path, 'wb') { |csv| data.to_a.each { |elem| csv << elem } }
1854
- elsif ['json', 'msgpack'].include? output_format
1651
+ elsif ['json', 'msgpack'].include? args[:output_format]
1855
1652
  # Assemble data
1856
1653
  h = {}
1857
1654
  h['Time'] = data[2..-1]
1858
1655
  h['TimeDST'] = timestamps2[2..-1] if timestamps_dst
1859
1656
  h['TimeUTC'] = timestamps3[2..-1] if timestamps_utc
1860
1657
 
1861
- [total_energy_data, fuel_data, end_use_data, emissions_data, emission_fuel_data,
1658
+ [total_energy_data, fuel_data, end_use_data, system_use_data, emissions_data, emission_fuel_data,
1862
1659
  emission_end_use_data, hot_water_use_data, total_loads_data, comp_loads_data, unmet_hours_data,
1863
1660
  zone_temps_data, airflows_data, weather_data, output_variables_data].each do |d|
1864
1661
  d.each do |o|
@@ -1869,16 +1666,29 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1869
1666
  end
1870
1667
 
1871
1668
  # Write file
1872
- if output_format == 'json'
1669
+ if args[:output_format] == 'json'
1873
1670
  require 'json'
1874
1671
  File.open(timeseries_output_path, 'w') { |json| json.write(JSON.pretty_generate(h)) }
1875
- elsif output_format == 'msgpack'
1672
+ elsif args[:output_format] == 'msgpack'
1876
1673
  File.open(timeseries_output_path, 'w') { |json| h.to_msgpack(json) }
1877
1674
  end
1878
1675
  end
1879
1676
  runner.registerInfo("Wrote timeseries output results to #{timeseries_output_path}.")
1880
1677
  end
1881
1678
 
1679
+ def get_dst_start_end_indexes(timestamps, timestamps_dst)
1680
+ dst_start_ix = nil
1681
+ dst_end_ix = nil
1682
+ timestamps.zip(timestamps_dst).each_with_index do |ts, i|
1683
+ dst_start_ix = i if ts[0] != ts[1] && dst_start_ix.nil?
1684
+ dst_end_ix = i if ts[0] == ts[1] && dst_end_ix.nil? && !dst_start_ix.nil?
1685
+ end
1686
+
1687
+ dst_end_ix = timestamps.size - 1 if dst_end_ix.nil? # run period ends before DST ends
1688
+
1689
+ return dst_start_ix, dst_end_ix
1690
+ end
1691
+
1882
1692
  def get_report_meter_data_annual(meter_names, unit_conv = UnitConversions.convert(1.0, 'J', 'MBtu'))
1883
1693
  return 0.0 if meter_names.empty?
1884
1694
 
@@ -1908,7 +1718,10 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1908
1718
  def get_report_meter_data_timeseries(meter_names, unit_conv, unit_adder, timeseries_frequency)
1909
1719
  return [0.0] * @timestamps.size if meter_names.empty?
1910
1720
 
1911
- msgpack_timeseries_name = OutputMethods.msgpack_frequency_map[timeseries_frequency]
1721
+ msgpack_timeseries_name = { 'timestep' => 'TimeStep',
1722
+ 'hourly' => 'Hourly',
1723
+ 'daily' => 'Daily',
1724
+ 'monthly' => 'Monthly' }[timeseries_frequency]
1912
1725
  cols = @msgpackData['MeterData'][msgpack_timeseries_name]['Cols']
1913
1726
  rows = @msgpackData['MeterData'][msgpack_timeseries_name]['Rows']
1914
1727
  indexes = cols.each_index.select { |i| meter_names.include? cols[i]['Variable'] }
@@ -1930,8 +1743,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1930
1743
  if key_values.uniq.size > 1 && key_values.include?('EMS') && ems_shift
1931
1744
  # Split into EMS and non-EMS queries so that the EMS values shift occurs for just the EMS query
1932
1745
  # Remove this code if we ever figure out a better way to handle when EMS output should shift
1933
- values = get_report_variable_data_timeseries(['EMS'], variables, unit_conv, unit_adder, timeseries_frequency, is_negative: is_negative, ems_shift: ems_shift)
1934
- sum_values = values.zip(get_report_variable_data_timeseries(key_values.select { |k| k != 'EMS' }, variables, unit_conv, unit_adder, timeseries_frequency, is_negative: is_negative, ems_shift: ems_shift)).map { |x, y| x + y }
1746
+ ems_indices = key_values.each_index.select { |i| key_values[i] == 'EMS' }
1747
+ ems_key_values = key_values.select.with_index { |_kv, i| ems_indices.include? i }
1748
+ ems_variables = variables.select.with_index { |_kv, i| ems_indices.include? i }
1749
+ non_ems_key_values = key_values.select.with_index { |_kv, i| !ems_indices.include? i }
1750
+ non_ems_variables = variables.select.with_index { |_kv, i| !ems_indices.include? i }
1751
+ values = get_report_variable_data_timeseries(ems_key_values, ems_variables, unit_conv, unit_adder, timeseries_frequency, is_negative: is_negative, ems_shift: ems_shift)
1752
+ non_ems_values = get_report_variable_data_timeseries(non_ems_key_values, non_ems_variables, unit_conv, unit_adder, timeseries_frequency, is_negative: is_negative, ems_shift: ems_shift)
1753
+ sum_values = [values, non_ems_values].transpose.map(&:sum)
1935
1754
  return sum_values
1936
1755
  end
1937
1756
 
@@ -1993,7 +1812,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1993
1812
  next if table['TableName'] != table_name
1994
1813
 
1995
1814
  cols = table['Cols']
1996
- index = cols.each_index.select { |i| cols[i] == "#{col_name} [#{units}]" }[0]
1815
+ index = cols.each_index.find { |i| cols[i] == "#{col_name} [#{units}]" }
1997
1816
  row_names.each do |row_name|
1998
1817
  vals << table['Rows'][row_name][index].to_f
1999
1818
  end
@@ -2015,8 +1834,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2015
1834
  if not obj.timeseries_output_by_system.empty?
2016
1835
  orig_values = obj.timeseries_output_by_system[sys_id]
2017
1836
  obj.timeseries_output_by_system[sys_id] = obj.timeseries_output_by_system[sys_id].map { |x| x * mult }
2018
- diffs = obj.timeseries_output_by_system[sys_id].zip(orig_values).map { |x, y| x - y }
2019
1837
  if not sync_obj.nil?
1838
+ diffs = obj.timeseries_output_by_system[sys_id].zip(orig_values).map { |x, y| x - y }
2020
1839
  sync_obj.timeseries_output = sync_obj.timeseries_output.zip(diffs).map { |x, y| x + y }
2021
1840
  end
2022
1841
  end
@@ -2031,19 +1850,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2031
1850
  @object_variables_by_key = {}
2032
1851
  return if @model.nil?
2033
1852
 
2034
- @model.getModelObjects.each do |object|
1853
+ @model.getModelObjects.sort.each do |object|
2035
1854
  next if object.to_AdditionalProperties.is_initialized
2036
1855
 
2037
- [EUT, HWT, LT, ILT].each do |class_name|
2038
- vars_by_key = get_object_output_variables_by_key(@model, object, class_name)
2039
- next if vars_by_key.size == 0
2040
-
1856
+ [EUT, HWT, LT].each do |class_name|
2041
1857
  sys_id = object.additionalProperties.getFeatureAsString('HPXML_ID')
2042
- if sys_id.is_initialized
2043
- sys_id = sys_id.get
2044
- else
2045
- sys_id = nil
2046
- end
1858
+ 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
2047
1861
 
2048
1862
  vars_by_key.each do |key, output_vars|
2049
1863
  output_vars.each do |output_var|
@@ -2116,8 +1930,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2116
1930
  @timeseries_output_by_fuel = {}
2117
1931
  @annual_output_by_fuel = {}
2118
1932
  @annual_output_by_end_use = {}
1933
+ @net_annual_output = 0.0
1934
+ @net_timeseries_output = []
2119
1935
  end
2120
- attr_accessor(:annual_output_by_fuel, :annual_output_by_end_use, :timeseries_output_by_fuel, :timeseries_output_by_end_use)
1936
+ attr_accessor(:annual_output_by_fuel, :annual_output_by_end_use, :timeseries_output_by_fuel, :timeseries_output_by_end_use,
1937
+ :net_annual_output, :net_timeseries_output)
2121
1938
  end
2122
1939
 
2123
1940
  class HotWater < BaseOutput
@@ -2131,12 +1948,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2131
1948
  end
2132
1949
 
2133
1950
  class PeakFuel < BaseOutput
2134
- def initialize(meters:, report:)
1951
+ def initialize(report:)
2135
1952
  super()
2136
- @meters = meters
2137
1953
  @report = report
2138
1954
  end
2139
- attr_accessor(:meters, :report)
1955
+ attr_accessor(:report)
2140
1956
  end
2141
1957
 
2142
1958
  class Load < BaseOutput
@@ -2235,8 +2051,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2235
2051
 
2236
2052
  @end_uses = {}
2237
2053
  @end_uses[[FT::Elec, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Heating]))
2238
- @end_uses[[FT::Elec, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HeatingHeatPumpBackup]))
2239
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]))
2240
2057
  @end_uses[[FT::Elec, EUT::Cooling]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Cooling]))
2241
2058
  @end_uses[[FT::Elec, EUT::CoolingFanPump]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::CoolingFanPump]))
2242
2059
  @end_uses[[FT::Elec, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::HotWater]))
@@ -2402,10 +2219,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2402
2219
  end
2403
2220
 
2404
2221
  # Peak Fuels
2405
- # Using meters for energy transferred in conditioned space only (i.e., excluding ducts) to determine winter vs summer.
2406
2222
  @peak_fuels = {}
2407
- @peak_fuels[[FT::Elec, PFT::Winter]] = PeakFuel.new(meters: ["Heating:EnergyTransfer:Zone:#{HPXML::LocationLivingSpace.upcase}"], report: 'Peak Electricity Winter Total')
2408
- @peak_fuels[[FT::Elec, PFT::Summer]] = PeakFuel.new(meters: ["Cooling:EnergyTransfer:Zone:#{HPXML::LocationLivingSpace.upcase}"], report: 'Peak Electricity Summer Total')
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')
2409
2225
 
2410
2226
  @peak_fuels.each do |key, peak_fuel|
2411
2227
  fuel_type, peak_fuel_type = key
@@ -2417,6 +2233,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2417
2233
 
2418
2234
  @loads = {}
2419
2235
  @loads[LT::Heating] = Load.new(ems_variable: 'loads_htg_tot')
2236
+ @loads[LT::HeatingHeatPumpBackup] = Load.new(variables: get_object_variables(LT, LT::HeatingHeatPumpBackup))
2420
2237
  @loads[LT::Cooling] = Load.new(ems_variable: 'loads_clg_tot')
2421
2238
  @loads[LT::HotWaterDelivered] = Load.new(variables: get_object_variables(LT, LT::HotWaterDelivered))
2422
2239
  @loads[LT::HotWaterTankLosses] = Load.new(variables: get_object_variables(LT, LT::HotWaterTankLosses),
@@ -2440,8 +2257,10 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2440
2257
  @component_loads[[LT::Heating, CLT::RimJoists]] = ComponentLoad.new(ems_variable: 'loads_htg_rim_joists')
2441
2258
  @component_loads[[LT::Heating, CLT::FoundationWalls]] = ComponentLoad.new(ems_variable: 'loads_htg_foundation_walls')
2442
2259
  @component_loads[[LT::Heating, CLT::Doors]] = ComponentLoad.new(ems_variable: 'loads_htg_doors')
2443
- @component_loads[[LT::Heating, CLT::Windows]] = ComponentLoad.new(ems_variable: 'loads_htg_windows')
2444
- @component_loads[[LT::Heating, CLT::Skylights]] = ComponentLoad.new(ems_variable: 'loads_htg_skylights')
2260
+ @component_loads[[LT::Heating, CLT::WindowsConduction]] = ComponentLoad.new(ems_variable: 'loads_htg_windows_conduction')
2261
+ @component_loads[[LT::Heating, CLT::WindowsSolar]] = ComponentLoad.new(ems_variable: 'loads_htg_windows_solar')
2262
+ @component_loads[[LT::Heating, CLT::SkylightsConduction]] = ComponentLoad.new(ems_variable: 'loads_htg_skylights_conduction')
2263
+ @component_loads[[LT::Heating, CLT::SkylightsSolar]] = ComponentLoad.new(ems_variable: 'loads_htg_skylights_solar')
2445
2264
  @component_loads[[LT::Heating, CLT::Floors]] = ComponentLoad.new(ems_variable: 'loads_htg_floors')
2446
2265
  @component_loads[[LT::Heating, CLT::Slabs]] = ComponentLoad.new(ems_variable: 'loads_htg_slabs')
2447
2266
  @component_loads[[LT::Heating, CLT::InternalMass]] = ComponentLoad.new(ems_variable: 'loads_htg_internal_mass')
@@ -2451,14 +2270,17 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2451
2270
  @component_loads[[LT::Heating, CLT::WholeHouseFan]] = ComponentLoad.new(ems_variable: 'loads_htg_whf')
2452
2271
  @component_loads[[LT::Heating, CLT::Ducts]] = ComponentLoad.new(ems_variable: 'loads_htg_ducts')
2453
2272
  @component_loads[[LT::Heating, CLT::InternalGains]] = ComponentLoad.new(ems_variable: 'loads_htg_intgains')
2273
+ @component_loads[[LT::Heating, CLT::Lighting]] = ComponentLoad.new(ems_variable: 'loads_htg_lighting')
2454
2274
  @component_loads[[LT::Cooling, CLT::Roofs]] = ComponentLoad.new(ems_variable: 'loads_clg_roofs')
2455
2275
  @component_loads[[LT::Cooling, CLT::Ceilings]] = ComponentLoad.new(ems_variable: 'loads_clg_ceilings')
2456
2276
  @component_loads[[LT::Cooling, CLT::Walls]] = ComponentLoad.new(ems_variable: 'loads_clg_walls')
2457
2277
  @component_loads[[LT::Cooling, CLT::RimJoists]] = ComponentLoad.new(ems_variable: 'loads_clg_rim_joists')
2458
2278
  @component_loads[[LT::Cooling, CLT::FoundationWalls]] = ComponentLoad.new(ems_variable: 'loads_clg_foundation_walls')
2459
2279
  @component_loads[[LT::Cooling, CLT::Doors]] = ComponentLoad.new(ems_variable: 'loads_clg_doors')
2460
- @component_loads[[LT::Cooling, CLT::Windows]] = ComponentLoad.new(ems_variable: 'loads_clg_windows')
2461
- @component_loads[[LT::Cooling, CLT::Skylights]] = ComponentLoad.new(ems_variable: 'loads_clg_skylights')
2280
+ @component_loads[[LT::Cooling, CLT::WindowsConduction]] = ComponentLoad.new(ems_variable: 'loads_clg_windows_conduction')
2281
+ @component_loads[[LT::Cooling, CLT::WindowsSolar]] = ComponentLoad.new(ems_variable: 'loads_clg_windows_solar')
2282
+ @component_loads[[LT::Cooling, CLT::SkylightsConduction]] = ComponentLoad.new(ems_variable: 'loads_clg_skylights_conduction')
2283
+ @component_loads[[LT::Cooling, CLT::SkylightsSolar]] = ComponentLoad.new(ems_variable: 'loads_clg_skylights_solar')
2462
2284
  @component_loads[[LT::Cooling, CLT::Floors]] = ComponentLoad.new(ems_variable: 'loads_clg_floors')
2463
2285
  @component_loads[[LT::Cooling, CLT::Slabs]] = ComponentLoad.new(ems_variable: 'loads_clg_slabs')
2464
2286
  @component_loads[[LT::Cooling, CLT::InternalMass]] = ComponentLoad.new(ems_variable: 'loads_clg_internal_mass')
@@ -2468,6 +2290,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2468
2290
  @component_loads[[LT::Cooling, CLT::WholeHouseFan]] = ComponentLoad.new(ems_variable: 'loads_clg_whf')
2469
2291
  @component_loads[[LT::Cooling, CLT::Ducts]] = ComponentLoad.new(ems_variable: 'loads_clg_ducts')
2470
2292
  @component_loads[[LT::Cooling, CLT::InternalGains]] = ComponentLoad.new(ems_variable: 'loads_clg_intgains')
2293
+ @component_loads[[LT::Cooling, CLT::Lighting]] = ComponentLoad.new(ems_variable: 'loads_clg_lighting')
2471
2294
 
2472
2295
  @component_loads.each do |key, comp_load|
2473
2296
  load_type, comp_load_type = key
@@ -2487,16 +2310,6 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2487
2310
  unmet_hour.timeseries_units = 'hr'
2488
2311
  end
2489
2312
 
2490
- # Ideal System Loads (expected load that is not met by the HVAC systems)
2491
- @ideal_system_loads = {}
2492
- @ideal_system_loads[ILT::Heating] = IdealLoad.new(variables: get_object_variables(ILT, ILT::Heating))
2493
- @ideal_system_loads[ILT::Cooling] = IdealLoad.new(variables: get_object_variables(ILT, ILT::Cooling))
2494
-
2495
- @ideal_system_loads.each do |load_type, ideal_load|
2496
- ideal_load.name = "Ideal System Load: #{load_type}"
2497
- ideal_load.annual_units = 'MBtu'
2498
- end
2499
-
2500
2313
  # Peak Loads
2501
2314
  @peak_loads = {}
2502
2315
  @peak_loads[PLT::Heating] = PeakLoad.new(ems_variable: 'loads_htg_tot', report: 'Peak Heating Load')
@@ -2545,6 +2358,30 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2545
2358
  end
2546
2359
  end
2547
2360
 
2361
+ def setup_timeseries_includes(emissions, args)
2362
+ # To calculate timeseries emissions or timeseries fuel consumption, we also need to select timeseries
2363
+ # end use consumption because EnergyPlus results may be post-processed due to HVAC DSE.
2364
+ # TODO: This could be removed if we could account for DSE inside EnergyPlus.
2365
+ args = args.dup # We don't want to modify the original arguments
2366
+ args[:include_hourly_electric_end_use_consumptions] = false
2367
+ if not emissions.empty?
2368
+ args[:include_hourly_electric_end_use_consumptions] = true # Need hourly electricity values for Cambium
2369
+ if args[:include_timeseries_emissions] || args[:include_timeseries_emission_end_uses] || args[:include_timeseries_emission_fuels]
2370
+ args[:include_timeseries_fuel_consumptions] = true
2371
+ end
2372
+ end
2373
+ if args[:include_timeseries_total_consumptions]
2374
+ args[:include_timeseries_fuel_consumptions] = true
2375
+ end
2376
+ if args[:include_timeseries_fuel_consumptions]
2377
+ args[:include_timeseries_end_use_consumptions] = true
2378
+ end
2379
+ if args[:include_timeseries_system_use_consumptions]
2380
+ args[:include_timeseries_end_use_consumptions] = true
2381
+ end
2382
+ return args
2383
+ end
2384
+
2548
2385
  def is_heat_pump_backup(sys_id)
2549
2386
  return false if @hpxml.nil?
2550
2387
 
@@ -2563,14 +2400,24 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2563
2400
  return true
2564
2401
  end
2565
2402
 
2566
- if sys_id.include? '_DFHPBackup'
2567
- return true
2568
- end
2569
-
2570
2403
  return false
2571
2404
  end
2572
2405
 
2573
- def get_object_output_variables_by_key(model, object, class_name)
2406
+ def get_hpxml_system_ids
2407
+ # Returns a list of HPXML IDs corresponds to HVAC or water heating systems
2408
+ return [] if @hpxml.nil?
2409
+
2410
+ system_ids = []
2411
+ (@hpxml.hvac_systems + @hpxml.water_heating_systems + @hpxml.ventilation_fans).each do |system|
2412
+ system_ids << system.id
2413
+ end
2414
+ return system_ids
2415
+ end
2416
+
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]).
2420
+
2574
2421
  to_ft = { EPlus::FuelTypeElectricity => FT::Elec,
2575
2422
  EPlus::FuelTypeNaturalGas => FT::Gas,
2576
2423
  EPlus::FuelTypeOil => FT::Oil,
@@ -2579,16 +2426,6 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2579
2426
  EPlus::FuelTypeWoodPellets => FT::WoodPellets,
2580
2427
  EPlus::FuelTypeCoal => FT::Coal }
2581
2428
 
2582
- # For a given object, returns the output variables to be requested and associates
2583
- # them with the appropriate keys (e.g., [FT::Elec, EUT::Heating]).
2584
-
2585
- sys_id = object.additionalProperties.getFeatureAsString('HPXML_ID')
2586
- if sys_id.is_initialized
2587
- sys_id = sys_id.get
2588
- else
2589
- sys_id = nil
2590
- end
2591
-
2592
2429
  if class_name == EUT
2593
2430
 
2594
2431
  # End uses
@@ -2606,9 +2443,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2606
2443
  elsif object.to_CoilHeatingGas.is_initialized
2607
2444
  fuel = object.to_CoilHeatingGas.get.fuelType
2608
2445
  if not is_heat_pump_backup(sys_id)
2609
- return { [to_ft[fuel], EUT::Heating] => ["Heating Coil #{fuel} Energy"] }
2446
+ return { [to_ft[fuel], EUT::Heating] => ["Heating Coil #{fuel} Energy", "Heating Coil Ancillary #{fuel} Energy"] }
2610
2447
  else
2611
- return { [to_ft[fuel], EUT::HeatingHeatPumpBackup] => ["Heating Coil #{fuel} Energy"] }
2448
+ return { [to_ft[fuel], EUT::HeatingHeatPumpBackup] => ["Heating Coil #{fuel} Energy", "Heating Coil Ancillary #{fuel} Energy"] }
2612
2449
  end
2613
2450
 
2614
2451
  elsif object.to_CoilHeatingWaterToAirHeatPumpEquationFit.is_initialized
@@ -2756,7 +2593,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2756
2593
  if object.name.to_s.end_with? Constants.ObjectNameFanPumpDisaggregatePrimaryHeat
2757
2594
  return { [FT::Elec, EUT::HeatingFanPump] => [object.name.to_s] }
2758
2595
  elsif object.name.to_s.end_with? Constants.ObjectNameFanPumpDisaggregateBackupHeat
2759
- return { [FT::Elec, EUT::HeatingFanPump] => [object.name.to_s] }
2596
+ return { [FT::Elec, EUT::HeatingHeatPumpBackupFanPump] => [object.name.to_s] }
2760
2597
  elsif object.name.to_s.end_with? Constants.ObjectNameFanPumpDisaggregateCool
2761
2598
  return { [FT::Elec, EUT::CoolingFanPump] => [object.name.to_s] }
2762
2599
  elsif object.name.to_s.include? Constants.ObjectNameWaterHeaterAdjustment(nil)
@@ -2764,6 +2601,9 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2764
2601
  return { [to_ft[fuel], EUT::HotWater] => [object.name.to_s] }
2765
2602
  elsif object.name.to_s.include? Constants.ObjectNameBatteryLossesAdjustment(nil)
2766
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] }
2767
2607
  else
2768
2608
  return { ems: [object.name.to_s] }
2769
2609
  end
@@ -2809,20 +2649,24 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2809
2649
  elsif object.to_CoilWaterHeatingDesuperheater.is_initialized
2810
2650
  return { LT::HotWaterDesuperheater => ['Water Heater Heating Energy'] }
2811
2651
 
2812
- elsif object.to_CoilHeatingDXSingleSpeed.is_initialized || object.to_CoilHeatingDXMultiSpeed.is_initialized || object.to_CoilHeatingGas.is_initialized
2813
- # Needed to apportion heating loads for dual-fuel heat pumps
2814
- return { LT::Heating => ['Heating Coil Heating Energy'] }
2815
-
2816
- end
2817
-
2818
- elsif class_name == ILT
2652
+ 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
2657
+ end
2819
2658
 
2820
- # Ideal Load
2659
+ 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
2664
+ end
2821
2665
 
2822
- if object.to_ZoneHVACIdealLoadsAirSystem.is_initialized
2823
- if object.name.to_s == Constants.ObjectNameIdealAirSystem
2824
- return { ILT::Heating => ['Zone Ideal Loads Zone Sensible Heating Energy'],
2825
- ILT::Cooling => ['Zone Ideal Loads Zone Sensible Cooling Energy'] }
2666
+ elsif object.to_EnergyManagementSystemOutputVariable.is_initialized
2667
+ if object.name.to_s.end_with? Constants.ObjectNameFanPumpDisaggregateBackupHeat
2668
+ # Fan/pump energy is contributing to the load
2669
+ return { LT::HeatingHeatPumpBackup => [object.name.to_s] }
2826
2670
  end
2827
2671
 
2828
2672
  end