urbanopt-cli 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (649) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -6
  3. data/CHANGELOG.md +14 -0
  4. data/CMakeLists.txt +7 -7
  5. data/Gemfile +3 -1
  6. data/README.md +9 -0
  7. data/example_files/Gemfile +23 -16
  8. data/example_files/Gemfile.lock +177 -0
  9. data/example_files/base_workflow_res.osw +57 -14
  10. data/example_files/class_project_coincident.json +1322 -0
  11. data/example_files/class_project_diverse.json +1322 -0
  12. data/example_files/disco/config.json +42 -0
  13. data/example_files/disco/cost_database.xlsx +0 -0
  14. data/example_files/disco/technical_catalog.json +12126 -0
  15. data/example_files/mappers/Baseline.rb +10 -7
  16. data/example_files/mappers/ChilledWaterStorage.rb +98 -0
  17. data/example_files/mappers/ClassProject.rb +110 -0
  18. data/example_files/mappers/CreateBar.rb +1 -0
  19. data/example_files/mappers/HighEfficiency.rb +13 -11
  20. data/example_files/mappers/PeakHoursMelsShedding.rb +72 -0
  21. data/example_files/mappers/PeakHoursThermostatAdjust.rb +78 -0
  22. data/example_files/mappers/ThermalStorage.rb +1 -0
  23. data/example_files/mappers/base_workflow.osw +55 -14
  24. data/example_files/mappers/class_project_workflow.osw +328 -0
  25. data/example_files/mappers/createbar_workflow.osw +16 -16
  26. data/example_files/measures/BuildResidentialModel/measure.rb +7 -1
  27. data/example_files/measures/BuildResidentialModel/measure.xml +1313 -706
  28. data/example_files/opendss/electrical_database.json +1446 -1446
  29. data/example_files/python_deps/dependencies.json +5 -0
  30. data/example_files/python_deps/install_python.ps1 +96 -0
  31. data/example_files/python_deps/install_python.sh +120 -0
  32. data/example_files/residential/clothes_dryer.tsv +11 -11
  33. data/example_files/residential/clothes_washer.tsv +3 -3
  34. data/example_files/residential/dishwasher.tsv +3 -3
  35. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +0 -1
  36. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +8 -21
  37. data/example_files/resources/hpxml-measures/.gitignore +2 -0
  38. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +1272 -1094
  39. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +978 -659
  40. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +52 -74
  41. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +77 -140
  42. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.rb +30 -27
  43. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml +32 -13
  44. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb +55 -51
  45. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/tests/build_residential_schedule_file_test.rb +89 -16
  46. data/example_files/resources/hpxml-measures/Changelog.md +65 -0
  47. data/example_files/resources/hpxml-measures/Gemfile +2 -4
  48. data/example_files/resources/hpxml-measures/Gemfile.lock +2 -13
  49. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +276 -300
  50. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +221 -215
  51. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +215 -170
  52. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/battery.rb +108 -16
  53. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +24 -44
  54. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +564 -197
  55. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/cambium/README.md +8 -8
  56. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +1 -0
  57. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +7 -55
  58. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +24 -19
  59. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +541 -211
  60. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +300 -172
  61. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXML.xsd +0 -2
  62. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLBaseElements.xsd +230 -141
  63. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLDataTypes.xsd +145 -137
  64. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml +191 -97
  65. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/iso-schematron.xsd +391 -0
  66. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +194 -198
  67. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +140 -145
  68. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +11 -11
  69. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +33 -1
  70. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb +4 -4
  71. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +17 -9
  72. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +14 -12
  73. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/output.rb +39 -17
  74. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/psychrometrics.rb +1 -1
  75. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/battery.csv +8761 -0
  76. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +114 -57
  77. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +1 -0
  78. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb +148 -0
  79. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +2 -2
  80. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +85 -127
  81. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/weather.rb +26 -32
  82. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +2 -14
  83. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlvalidator.rb +67 -0
  84. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +117 -56
  85. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_battery.rb +141 -14
  86. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +453 -344
  87. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +124 -20
  88. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +1 -1
  89. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +28 -32
  90. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +172 -79
  91. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +54 -8
  92. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +3 -3
  93. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +4 -4
  94. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +7 -7
  95. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +1 -1
  96. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_schedules.rb +6 -9
  97. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +8 -8
  98. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +213 -95
  99. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +1 -10
  100. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_weather.rb +76 -0
  101. data/example_files/resources/hpxml-measures/README.md +2 -3
  102. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.rb +585 -287
  103. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.xml +304 -352
  104. data/example_files/resources/hpxml-measures/ReportSimulationOutput/tests/output_report_test.rb +404 -279
  105. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.rb +222 -501
  106. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.xml +137 -200
  107. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Annual Charge.json +649 -0
  108. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Monthly Charge.json +649 -0
  109. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json +647 -0
  110. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate Min Annual Charge.json +8776 -0
  111. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate Min Monthly Charge.json +8776 -0
  112. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json +8774 -0
  113. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate Min Annual Charge.json +659 -0
  114. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate Min Monthly Charge.json +659 -0
  115. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json +657 -0
  116. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate Min Annual Charge.json +670 -0
  117. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate Min Monthly Charge.json +670 -0
  118. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json +668 -0
  119. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate Min Annual Charge.json +655 -0
  120. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate Min Monthly Charge.json +655 -0
  121. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json +653 -0
  122. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/openei_rates.zip +0 -0
  123. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/Average_retail_price_of_electricity.csv +0 -0
  124. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/HouseholdConsumption.csv +0 -0
  125. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/NG_PRI_SUM_A_EPG0_PRS_DMCF_A.csv +0 -0
  126. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/PET_PRI_WFR_A_EPD2F_PRS_DPGAL_W.csv +0 -0
  127. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/PET_PRI_WFR_A_EPLLPA_PRS_DPGAL_W.csv +0 -0
  128. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/README.md +0 -0
  129. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/util.rb +506 -25
  130. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Contains Demand Charges.json +1312 -0
  131. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Invalid Fixed Charge Units.json +657 -0
  132. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Invalid Min Charge Units.json +659 -0
  133. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/JacksonElectricMemberCorp-ResidentialSeniorCitizenLowIncomeAssistance.json +681 -0
  134. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Missing Required Fields.json +54 -0
  135. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/data.csv +8761 -0
  136. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/utility_bills_test.rb +1006 -235
  137. data/example_files/resources/hpxml-measures/docs/source/conf.py +1 -1
  138. data/example_files/resources/hpxml-measures/docs/source/intro.rst +0 -1
  139. data/example_files/resources/hpxml-measures/docs/source/usage_instructions.rst +2 -2
  140. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +461 -261
  141. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +146 -152
  142. data/example_files/resources/hpxml-measures/tasks.rb +616 -802
  143. data/example_files/resources/hpxml-measures/workflow/real_homes/house001.xml +19 -11
  144. data/example_files/resources/hpxml-measures/workflow/real_homes/house002.xml +20 -12
  145. data/example_files/resources/hpxml-measures/workflow/real_homes/house003.xml +12 -7
  146. data/example_files/resources/hpxml-measures/workflow/real_homes/house004.xml +12 -7
  147. data/example_files/resources/hpxml-measures/workflow/real_homes/house005.xml +19 -11
  148. data/example_files/resources/hpxml-measures/workflow/real_homes/house006.xml +12 -7
  149. data/example_files/resources/hpxml-measures/workflow/real_homes/house007.xml +20 -12
  150. data/example_files/resources/hpxml-measures/workflow/real_homes/house008.xml +28 -16
  151. data/example_files/resources/hpxml-measures/workflow/real_homes/house009.xml +28 -17
  152. data/example_files/resources/hpxml-measures/workflow/real_homes/house010.xml +28 -16
  153. data/example_files/resources/hpxml-measures/workflow/real_homes/house011.xml +20 -12
  154. data/example_files/resources/hpxml-measures/workflow/real_homes/house012.xml +20 -12
  155. data/example_files/resources/hpxml-measures/workflow/real_homes/house013.xml +20 -12
  156. data/example_files/resources/hpxml-measures/workflow/real_homes/house014.xml +20 -12
  157. data/example_files/resources/hpxml-measures/workflow/real_homes/house015.xml +20 -12
  158. data/example_files/resources/hpxml-measures/workflow/real_homes/house016.xml +22 -12
  159. data/example_files/resources/hpxml-measures/workflow/real_homes/house017.xml +19 -11
  160. data/example_files/resources/hpxml-measures/workflow/real_homes/house018.xml +20 -12
  161. data/example_files/resources/hpxml-measures/workflow/real_homes/house019.xml +13 -7
  162. data/example_files/resources/hpxml-measures/workflow/real_homes/house020.xml +12 -7
  163. data/example_files/resources/hpxml-measures/workflow/real_homes/house021.xml +31 -16
  164. data/example_files/resources/hpxml-measures/workflow/real_homes/house022.xml +22 -12
  165. data/example_files/resources/hpxml-measures/workflow/real_homes/house023.xml +21 -12
  166. data/example_files/resources/hpxml-measures/workflow/real_homes/house024.xml +37 -22
  167. data/example_files/resources/hpxml-measures/workflow/real_homes/house025.xml +24 -12
  168. data/example_files/resources/hpxml-measures/workflow/real_homes/house026.xml +33 -21
  169. data/example_files/resources/hpxml-measures/workflow/real_homes/house027.xml +28 -16
  170. data/example_files/resources/hpxml-measures/workflow/real_homes/house028.xml +28 -16
  171. data/example_files/resources/hpxml-measures/workflow/real_homes/house029.xml +30 -17
  172. data/example_files/resources/hpxml-measures/workflow/real_homes/house030.xml +10 -7
  173. data/example_files/resources/hpxml-measures/workflow/real_homes/house031.xml +22 -11
  174. data/example_files/resources/hpxml-measures/workflow/real_homes/house032.xml +12 -7
  175. data/example_files/resources/hpxml-measures/workflow/real_homes/house033.xml +18 -12
  176. data/example_files/resources/hpxml-measures/workflow/real_homes/house034.xml +25 -16
  177. data/example_files/resources/hpxml-measures/workflow/real_homes/house035.xml +22 -12
  178. data/example_files/resources/hpxml-measures/workflow/real_homes/house036.xml +20 -12
  179. data/example_files/resources/hpxml-measures/workflow/real_homes/house037.xml +26 -17
  180. data/example_files/resources/hpxml-measures/workflow/real_homes/house038.xml +19 -11
  181. data/example_files/resources/hpxml-measures/workflow/real_homes/house039.xml +25 -16
  182. data/example_files/resources/hpxml-measures/workflow/real_homes/house040.xml +20 -12
  183. data/example_files/resources/hpxml-measures/workflow/real_homes/house041.xml +35 -21
  184. data/example_files/resources/hpxml-measures/workflow/real_homes/house042.xml +28 -17
  185. data/example_files/resources/hpxml-measures/workflow/real_homes/house043.xml +20 -12
  186. data/example_files/resources/hpxml-measures/workflow/real_homes/house044.xml +35 -21
  187. data/example_files/resources/hpxml-measures/workflow/real_homes/house045.xml +20 -12
  188. data/example_files/resources/hpxml-measures/workflow/real_homes/house046.xml +20 -13
  189. data/example_files/resources/hpxml-measures/workflow/real_homes/house047.xml +12 -9
  190. data/example_files/resources/hpxml-measures/workflow/real_homes/house048.xml +25 -14
  191. data/example_files/resources/hpxml-measures/workflow/real_homes/house049.xml +10 -7
  192. data/example_files/resources/hpxml-measures/workflow/real_homes/house050.xml +20 -11
  193. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +91 -88
  194. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +18 -7
  195. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +546 -535
  196. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +546 -535
  197. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +555 -544
  198. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +18 -7
  199. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +18 -7
  200. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +18 -7
  201. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +18 -7
  202. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil-location-miami-fl.xml +580 -569
  203. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +18 -7
  204. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane-location-portland-or.xml +580 -569
  205. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +18 -7
  206. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +18 -7
  207. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +7 -0
  208. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +17 -6
  209. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +7 -0
  210. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +18 -7
  211. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +18 -7
  212. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +18 -7
  213. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery-scheduled.xml +600 -0
  214. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery.xml +598 -587
  215. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml +494 -485
  216. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +606 -593
  217. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml +494 -485
  218. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-heated-space.xml +494 -485
  219. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml +494 -485
  220. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-calctype-operational.xml +480 -471
  221. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +464 -457
  222. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +496 -487
  223. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +466 -459
  224. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +518 -509
  225. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +513 -504
  226. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +445 -438
  227. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +476 -467
  228. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +443 -436
  229. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +446 -439
  230. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +494 -485
  231. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +445 -438
  232. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +476 -467
  233. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +446 -439
  234. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +494 -485
  235. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +489 -480
  236. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +499 -490
  237. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +491 -482
  238. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room-multiple-water-heaters.xml +510 -0
  239. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +495 -486
  240. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-multiple.xml +709 -695
  241. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +528 -519
  242. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +512 -503
  243. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +504 -495
  244. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +497 -488
  245. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +490 -481
  246. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +487 -478
  247. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached-2stories.xml +639 -628
  248. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached-atticroof-cathedral.xml +587 -580
  249. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached.xml +639 -628
  250. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-defaults.xml +539 -528
  251. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-loads-large-uncommon.xml +644 -633
  252. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-loads-large-uncommon2.xml +644 -633
  253. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational.xml +575 -564
  254. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +16 -7
  255. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +16 -7
  256. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +18 -7
  257. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +585 -574
  258. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +18 -7
  259. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +18 -7
  260. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +18 -7
  261. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +18 -7
  262. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +18 -7
  263. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-detailed-setpoints.xml +536 -0
  264. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +16 -7
  265. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +16 -7
  266. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +20 -8
  267. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +16 -7
  268. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +16 -7
  269. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +18 -7
  270. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +18 -7
  271. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +18 -7
  272. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +16 -7
  273. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +18 -7
  274. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +16 -7
  275. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +18 -7
  276. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +19 -8
  277. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +19 -8
  278. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +19 -8
  279. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +19 -8
  280. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +19 -8
  281. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +18 -7
  282. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +18 -7
  283. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +18 -7
  284. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +18 -7
  285. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +18 -7
  286. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +18 -7
  287. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +18 -7
  288. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-detailed-setpoints.xml +582 -571
  289. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +583 -572
  290. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +18 -7
  291. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef-fhr.xml +584 -573
  292. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +584 -573
  293. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +18 -7
  294. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-detailed-schedules.xml +583 -572
  295. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-operating-mode-heat-pump-only.xml +585 -574
  296. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +18 -7
  297. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +582 -571
  298. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +18 -7
  299. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +18 -7
  300. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +18 -7
  301. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified-detailed-occupancy-stochastic.xml +586 -575
  302. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified.xml +585 -574
  303. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +18 -7
  304. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +18 -7
  305. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-detailed-setpoints.xml +580 -569
  306. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +18 -7
  307. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +580 -569
  308. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +18 -7
  309. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +580 -569
  310. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +18 -7
  311. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +18 -7
  312. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +18 -7
  313. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +18 -7
  314. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +28 -11
  315. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +20 -7
  316. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +18 -7
  317. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +18 -7
  318. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +18 -7
  319. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +18 -7
  320. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-ceilingtypes.xml +607 -0
  321. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-floortypes.xml +550 -0
  322. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +27 -12
  323. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +18 -7
  324. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +18 -7
  325. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +18 -7
  326. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +18 -7
  327. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +18 -7
  328. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-orientations.xml +589 -578
  329. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +18 -7
  330. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +18 -7
  331. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-physical-properties.xml +619 -608
  332. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +620 -609
  333. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-storms.xml +618 -607
  334. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +18 -7
  335. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +537 -526
  336. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +90 -43
  337. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +2507 -2460
  338. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-thermal-mass.xml +595 -584
  339. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +19 -8
  340. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-natural-ventilation-availability.xml +584 -0
  341. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +18 -7
  342. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-physical-properties.xml +594 -583
  343. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading.xml +597 -586
  344. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-storms.xml +598 -587
  345. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +27 -12
  346. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +671 -656
  347. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +18 -7
  348. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +18 -7
  349. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-foundation-conditioned-basement-wall-interior-insulation.xml → base-foundation-conditioned-basement-wall-insulation.xml} +585 -574
  350. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-crawlspace.xml +582 -571
  351. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +35 -16
  352. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +18 -7
  353. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +27 -12
  354. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +27 -12
  355. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +27 -12
  356. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +27 -12
  357. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +27 -12
  358. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +27 -12
  359. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +18 -7
  360. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-backup-lockout-temperature.xml +586 -575
  361. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +573 -562
  362. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +580 -569
  363. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-seer2-hspf2.xml +583 -0
  364. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +18 -7
  365. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +18 -7
  366. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-switchover-temperature.xml +600 -589
  367. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml +599 -588
  368. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-furnace.xml +629 -616
  369. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +18 -7
  370. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +573 -562
  371. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +579 -568
  372. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +581 -570
  373. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +581 -570
  374. 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 +582 -0
  375. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +581 -570
  376. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-acca.xml +581 -570
  377. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-hers.xml +581 -570
  378. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-maxload.xml +581 -570
  379. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler.xml +598 -587
  380. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-furnace.xml +628 -615
  381. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-acca.xml +581 -570
  382. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-hers.xml +581 -570
  383. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-maxload.xml +581 -570
  384. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-elec-only.xml +535 -526
  385. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-central-ac-1-speed.xml +589 -578
  386. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-only.xml +536 -527
  387. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-1-speed.xml +18 -7
  388. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-2-speed.xml +565 -554
  389. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-var-speed.xml +565 -554
  390. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-plus-air-to-air-heat-pump-heating.xml +18 -7
  391. 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 +582 -571
  392. 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 +582 -571
  393. 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 +582 -571
  394. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted.xml +18 -7
  395. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-elec-resistance-only.xml +526 -517
  396. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-evap-cooler-furnace-gas.xml +573 -562
  397. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-floor-furnace-propane-only.xml +529 -520
  398. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-elec-only.xml +565 -554
  399. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-2-speed.xml +580 -569
  400. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-var-speed.xml +580 -569
  401. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +565 -554
  402. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-room-ac.xml +578 -567
  403. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +575 -564
  404. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +581 -570
  405. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-acca.xml +583 -572
  406. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-hers.xml +583 -572
  407. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-maxload.xml +583 -572
  408. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +18 -7
  409. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-cooling-only.xml +18 -7
  410. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-heating-only.xml +18 -7
  411. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-acca.xml +580 -569
  412. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-hers.xml +580 -569
  413. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-maxload.xml +580 -569
  414. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-stove.xml +551 -542
  415. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac-with-heating.xml +532 -530
  416. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac.xml +525 -516
  417. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-acca.xml +541 -532
  418. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-hers.xml +541 -532
  419. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-maxload.xml +541 -532
  420. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-only.xml +525 -516
  421. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-heating.xml +533 -0
  422. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-acca.xml +542 -0
  423. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-hers.xml +542 -0
  424. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-maxload.xml +542 -0
  425. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-stove-oil-only.xml +529 -520
  426. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-wall-furnace-elec-only.xml +529 -520
  427. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize.xml +580 -569
  428. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +16 -7
  429. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +16 -7
  430. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +18 -7
  431. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +16 -7
  432. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +16 -7
  433. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +16 -7
  434. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +16 -7
  435. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed-seer2.xml +567 -0
  436. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +18 -7
  437. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +18 -7
  438. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +18 -7
  439. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +18 -7
  440. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +16 -7
  441. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml +18 -7
  442. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +18 -7
  443. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +18 -7
  444. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +18 -7
  445. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +18 -7
  446. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-fractions.xml +611 -598
  447. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-multipliers.xml +589 -0
  448. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-cfm50.xml +582 -571
  449. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +18 -7
  450. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +16 -7
  451. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +18 -7
  452. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +17 -7
  453. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +16 -7
  454. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +530 -521
  455. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +530 -521
  456. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +530 -521
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +566 -555
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +18 -7
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +18 -7
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +18 -7
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +18 -7
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-detailed-setpoints.xml +566 -555
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +566 -555
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +18 -7
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +18 -7
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +18 -7
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +18 -7
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +16 -7
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +574 -563
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +581 -570
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +583 -572
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml +587 -576
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml +587 -576
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-var-speed.xml +587 -576
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-1-speed.xml +591 -580
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-2-speed.xml +591 -580
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-var-speed.xml +591 -580
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-only.xml +570 -559
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-ground-to-air-heat-pump.xml +586 -575
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-air-conditioner-only-ducted.xml +570 -559
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-heat-pump-ducted.xml +586 -575
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +18 -7
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +16 -7
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +18 -7
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +18 -7
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +18 -7
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-stove.xml +552 -543
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +16 -7
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +963 -938
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +33 -69
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +530 -521
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-electricity.xml +535 -0
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-ptac-with-heating.xml → base-hvac-ptac-with-heating-natural-gas.xml} +23 -21
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac.xml +526 -517
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp.xml +541 -532
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +16 -7
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-ceer.xml +526 -517
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-detailed-setpoints.xml +526 -517
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +16 -7
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-heating.xml +535 -0
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-reverse-cycle.xml +542 -0
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-seasons.xml +594 -583
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-schedules.xml +586 -575
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-setbacks.xml +18 -7
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +18 -7
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +530 -521
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +530 -521
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +18 -7
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +18 -7
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +530 -521
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +18 -7
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-holiday.xml +18 -7
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +18 -7
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +18 -7
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +27 -12
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-capetown-zaf.xml +591 -576
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +18 -7
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +27 -12
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +582 -571
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +537 -526
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +18 -7
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +537 -526
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +601 -586
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +18 -7
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +18 -7
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-airflow-fraction-zero.xml +601 -587
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +19 -7
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +20 -7
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-exhaust.xml +607 -0
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-supply.xml +607 -0
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +21 -7
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +18 -7
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +18 -7
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +18 -7
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +18 -7
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +18 -7
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +18 -7
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +37 -19
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +18 -7
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +18 -7
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-additional-properties.xml +590 -579
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-none.xml +578 -0
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-detailed-only.xml +632 -0
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-mixed.xml +614 -0
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv.xml +677 -0
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills.xml +593 -0
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +27 -9
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-emissions.xml +676 -665
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery-scheduled.xml +616 -0
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery.xml +615 -0
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +598 -587
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-ground-conductivity.xml +586 -0
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +18 -7
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +18 -7
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +18 -7
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +18 -7
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +583 -572
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +18 -7
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +1700 -1677
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-ah.xml +622 -611
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-garage.xml +697 -682
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-pv-battery-lifetime-model.xml → base-pv-battery-round-trip-efficiency.xml} +20 -11
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-scheduled.xml +624 -0
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery.xml +622 -611
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery-scheduled.xml +640 -0
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery.xml +639 -0
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators.xml +623 -0
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +606 -595
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-all-10-mins.xml +582 -571
  570. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-smooth.xml +583 -572
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-10-mins.xml +584 -0
  572. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-vacancy.xml +583 -572
  573. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic.xml +583 -572
  574. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-schedules.xml +581 -570
  575. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-setbacks.xml +581 -570
  576. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints.xml +581 -570
  577. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple.xml +636 -625
  578. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +18 -7
  579. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +27 -14
  580. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +21 -10
  581. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +21 -10
  582. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-dhw-tank-heat-pump-detailed-operating-modes.xml → base-simcontrol-temperature-capacitance-multiplier.xml} +25 -13
  583. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-10-mins.xml +584 -0
  584. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-60-mins.xml +584 -0
  585. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +18 -7
  586. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-dhw-tank-heat-pump-detailed-setpoints.xml → base-simcontrol-timestep-30-mins.xml} +25 -14
  587. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +18 -7
  588. data/example_files/resources/hpxml-measures/workflow/template-build-and-run-hpxml-with-stochastic-occupancy.osw +18 -13
  589. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy.osw +12 -7
  590. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml.osw +8 -24
  591. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +366 -358
  592. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +369 -361
  593. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +369 -361
  594. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +369 -361
  595. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +369 -361
  596. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +369 -361
  597. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +369 -361
  598. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +369 -361
  599. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +311 -303
  600. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +311 -303
  601. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +327 -319
  602. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +327 -319
  603. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +332 -324
  604. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +332 -324
  605. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +341 -333
  606. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +341 -333
  607. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +369 -361
  608. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +369 -361
  609. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +369 -361
  610. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +369 -361
  611. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +369 -361
  612. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +369 -361
  613. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +383 -379
  614. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +383 -379
  615. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +538 -534
  616. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +550 -546
  617. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +444 -410
  618. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_ashrae_140.csv +8 -8
  619. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_bills.csv +444 -410
  620. data/example_files/resources/hpxml-measures/workflow/tests/compare.py +18 -4
  621. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +133 -288
  622. data/example_files/scripts/convert_urbanopt_to_disco.py +130 -0
  623. data/example_files/scripts/default_control_changes.csv +8 -0
  624. data/example_files/scripts/default_voltage_regulators.csv +3 -0
  625. data/example_files/scripts/read_data.py +331 -0
  626. data/example_files/visualization/input_visualization_feature.html +172 -81
  627. data/example_files/visualization/input_visualization_scenario.html +178 -82
  628. data/example_files/xml_building/17/README.md +2 -2
  629. data/example_files/xml_building/17/unit 1.xml +40 -41
  630. data/example_files/xml_building/17/unit 2.xml +35 -36
  631. data/example_files/xml_building/17/unit 3.xml +35 -36
  632. data/example_files/xml_building/17/unit 4.xml +41 -42
  633. data/lib/uo_cli/version.rb +1 -1
  634. data/lib/uo_cli.rb +596 -96
  635. data/uo_cli.gemspec +6 -5
  636. metadata +121 -36
  637. data/example_files/residential/exhaust.tsv +0 -3
  638. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/hvac_equipment_efficiency.csv +0 -493
  639. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/water_heater_efficiency.csv +0 -157
  640. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/HPXMLvalidator.xml +0 -620
  641. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/validator.rb +0 -107
  642. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.rb +0 -450
  643. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.xml +0 -85
  644. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/resources/constants.rb +0 -72
  645. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/tests/hpxml_output_report_test.rb +0 -290
  646. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_10kW.csv +0 -8761
  647. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_1kW.csv +0 -8761
  648. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_None.csv +0 -8761
  649. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_hvac_sizing.csv +0 -410
@@ -29,16 +29,17 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
29
29
  end
30
30
 
31
31
  # define the arguments that the user will input
32
- def arguments(model)
32
+ def arguments(model) # rubocop:disable Lint/UnusedMethodArgument
33
33
  args = OpenStudio::Measure::OSArgumentVector.new
34
34
 
35
35
  format_chs = OpenStudio::StringVector.new
36
36
  format_chs << 'csv'
37
37
  format_chs << 'json'
38
38
  format_chs << 'msgpack'
39
+ format_chs << 'csv_dview'
39
40
  arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('output_format', format_chs, false)
40
41
  arg.setDisplayName('Output Format')
41
- arg.setDescription('The file format of the annual (and timeseries, if requested) outputs.')
42
+ arg.setDescription("The file format of the annual (and timeseries, if requested) outputs. If 'csv_dview' is selected, the timeseries CSV file will include header rows that facilitate opening the file in the DView application.")
42
43
  arg.setDefaultValue('csv')
43
44
  args << arg
44
45
 
@@ -78,6 +79,18 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
78
79
  arg.setDefaultValue(false)
79
80
  args << arg
80
81
 
82
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_emission_fuels', false)
83
+ arg.setDisplayName('Generate Timeseries Output: Emissions')
84
+ arg.setDescription('Generates timeseries emissions for each fuel type. Requires the appropriate HPXML inputs to be specified.')
85
+ arg.setDefaultValue(false)
86
+ args << arg
87
+
88
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_emission_end_uses', false)
89
+ arg.setDisplayName('Generate Timeseries Output: Emission End Uses')
90
+ arg.setDescription('Generates timeseries emissions for each end use. Requires the appropriate HPXML inputs to be specified.')
91
+ arg.setDefaultValue(false)
92
+ args << arg
93
+
81
94
  arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_hot_water_uses', false)
82
95
  arg.setDisplayName('Generate Timeseries Output: Hot Water Uses')
83
96
  arg.setDescription('Generates timeseries hot water usages for each end use.')
@@ -96,6 +109,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
96
109
  arg.setDefaultValue(false)
97
110
  args << arg
98
111
 
112
+ arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_unmet_hours', false)
113
+ arg.setDisplayName('Generate Timeseries Output: Unmet Hours')
114
+ arg.setDescription('Generates timeseries unmet hours for heating and cooling.')
115
+ arg.setDefaultValue(false)
116
+ args << arg
117
+
99
118
  arg = OpenStudio::Measure::OSArgument::makeBoolArgument('include_timeseries_zone_temperatures', false)
100
119
  arg.setDisplayName('Generate Timeseries Output: Zone Temperatures')
101
120
  arg.setDescription('Generates timeseries temperatures for each thermal zone.')
@@ -114,6 +133,15 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
114
133
  arg.setDefaultValue(false)
115
134
  args << arg
116
135
 
136
+ timestamp_chs = OpenStudio::StringVector.new
137
+ timestamp_chs << 'start'
138
+ timestamp_chs << 'end'
139
+ arg = OpenStudio::Measure::OSArgument::makeChoiceArgument('timeseries_timestamp_convention', timestamp_chs, false)
140
+ arg.setDisplayName('Generate Timeseries Output: Timestamp Convention')
141
+ arg.setDescription("Determines whether timeseries timestamps use the start-of-period or end-of-period convention. Doesn't apply if the output format is 'csv_dview'.")
142
+ arg.setDefaultValue('start')
143
+ args << arg
144
+
117
145
  arg = OpenStudio::Measure::OSArgument::makeBoolArgument('add_timeseries_dst_column', false)
118
146
  arg.setDisplayName('Generate Timeseries Output: Add TimeDST Column')
119
147
  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.')
@@ -131,6 +159,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
131
159
  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"')
132
160
  args << arg
133
161
 
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
+
134
167
  arg = OpenStudio::Measure::OSArgument::makeStringArgument('annual_output_file_name', false)
135
168
  arg.setDisplayName('Annual Output File Name')
136
169
  arg.setDescription("If not provided, defaults to 'results_annual.csv' (or 'results_annual.json' or 'results_annual.msgpack').")
@@ -148,7 +181,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
148
181
  def outputs
149
182
  outs = OpenStudio::Measure::OSOutputVector.new
150
183
 
151
- setup_outputs()
184
+ setup_outputs(true)
152
185
 
153
186
  all_outputs = []
154
187
  all_outputs << @totals
@@ -163,8 +196,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
163
196
 
164
197
  output_names = []
165
198
  all_outputs.each do |outputs|
166
- outputs.each do |key, obj|
167
- output_names << get_runner_output_name(obj)
199
+ outputs.values.each do |obj|
200
+ output_names << get_runner_output_name(obj.name, obj.annual_units)
168
201
  end
169
202
  end
170
203
 
@@ -194,6 +227,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
194
227
  return result
195
228
  end
196
229
 
230
+ unmet_hours_program = @model.getModelObjectByName(Constants.ObjectNameUnmetHoursProgram.gsub(' ', '_')).get.to_EnergyManagementSystemProgram.get
197
231
  total_loads_program = @model.getModelObjectByName(Constants.ObjectNameTotalLoadsProgram.gsub(' ', '_')).get.to_EnergyManagementSystemProgram.get
198
232
  comp_loads_program = @model.getModelObjectByName(Constants.ObjectNameComponentLoadsProgram.gsub(' ', '_'))
199
233
  if comp_loads_program.is_initialized
@@ -201,17 +235,21 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
201
235
  else
202
236
  comp_loads_program = nil
203
237
  end
238
+ has_heating = @model.getBuilding.additionalProperties.getFeatureAsBoolean('has_heating').get
239
+ has_cooling = @model.getBuilding.additionalProperties.getFeatureAsBoolean('has_cooling').get
204
240
 
205
- timeseries_frequency = runner.getOptionalStringArgumentValue('timeseries_frequency', user_arguments)
206
- timeseries_frequency = timeseries_frequency.is_initialized ? timeseries_frequency.get : 'none'
241
+ timeseries_frequency = runner.getStringArgumentValue('timeseries_frequency', user_arguments)
207
242
  if timeseries_frequency != 'none'
208
243
  include_timeseries_total_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_total_consumptions', user_arguments)
209
244
  include_timeseries_fuel_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_fuel_consumptions', user_arguments)
210
245
  include_timeseries_end_use_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_end_use_consumptions', user_arguments)
211
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)
212
249
  include_timeseries_hot_water_uses = runner.getOptionalBoolArgumentValue('include_timeseries_hot_water_uses', user_arguments)
213
250
  include_timeseries_total_loads = runner.getOptionalBoolArgumentValue('include_timeseries_total_loads', user_arguments)
214
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)
215
253
  include_timeseries_zone_temperatures = runner.getOptionalBoolArgumentValue('include_timeseries_zone_temperatures', user_arguments)
216
254
  include_timeseries_airflows = runner.getOptionalBoolArgumentValue('include_timeseries_airflows', user_arguments)
217
255
  include_timeseries_weather = runner.getOptionalBoolArgumentValue('include_timeseries_weather', user_arguments)
@@ -221,23 +259,26 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
221
259
  include_timeseries_fuel_consumptions = include_timeseries_fuel_consumptions.is_initialized ? include_timeseries_fuel_consumptions.get : false
222
260
  include_timeseries_end_use_consumptions = include_timeseries_end_use_consumptions.is_initialized ? include_timeseries_end_use_consumptions.get : false
223
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
224
264
  include_timeseries_hot_water_uses = include_timeseries_hot_water_uses.is_initialized ? include_timeseries_hot_water_uses.get : false
225
265
  include_timeseries_total_loads = include_timeseries_total_loads.is_initialized ? include_timeseries_total_loads.get : false
226
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
227
268
  include_timeseries_zone_temperatures = include_timeseries_zone_temperatures.is_initialized ? include_timeseries_zone_temperatures.get : false
228
269
  include_timeseries_airflows = include_timeseries_airflows.is_initialized ? include_timeseries_airflows.get : false
229
270
  include_timeseries_weather = include_timeseries_weather.is_initialized ? include_timeseries_weather.get : false
230
271
  user_output_variables = user_output_variables.is_initialized ? user_output_variables.get : nil
231
272
  end
232
273
 
233
- setup_outputs(user_output_variables)
274
+ setup_outputs(false, user_output_variables)
234
275
 
235
276
  # To calculate timeseries emissions or timeseries fuel consumption, we also need to select timeseries
236
277
  # end use consumption because EnergyPlus results may be post-processed due to HVAC DSE.
237
278
  # TODO: This could be removed if we could account for DSE inside EnergyPlus.
238
279
  if not @emissions.empty?
239
280
  include_hourly_electric_end_use_consumptions = true # Need hourly electricity values for Cambium
240
- if include_timeseries_emissions
281
+ if include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
241
282
  include_timeseries_fuel_consumptions = true
242
283
  end
243
284
  end
@@ -249,12 +290,17 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
249
290
  end
250
291
 
251
292
  has_electricity_production = false
252
- if @end_uses.select { |key, end_use| end_use.is_negative && end_use.variables.size > 0 }.size > 0
293
+ if @end_uses.select { |_key, end_use| end_use.is_negative && end_use.variables.size > 0 }.size > 0
253
294
  has_electricity_production = true
254
295
  end
255
296
 
297
+ has_electricity_storage = false
298
+ if @end_uses.select { |_key, end_use| end_use.is_storage && end_use.variables.size > 0 }.size > 0
299
+ has_electricity_storage = true
300
+ end
301
+
256
302
  # Fuel outputs
257
- @fuels.each do |fuel_type, fuel|
303
+ @fuels.each do |_fuel_type, fuel|
258
304
  fuel.meters.each do |meter|
259
305
  result << OpenStudio::IdfObject.load("Output:Meter,#{meter},runperiod;").get
260
306
  if include_timeseries_fuel_consumptions
@@ -262,11 +308,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
262
308
  end
263
309
  end
264
310
  end
265
- if has_electricity_production
311
+ if has_electricity_production || has_electricity_storage
266
312
  result << OpenStudio::IdfObject.load('Output:Meter,ElectricityProduced:Facility,runperiod;').get # Used for error checking
267
- if include_timeseries_fuel_consumptions
268
- result << OpenStudio::IdfObject.load("Output:Meter,ElectricityProduced:Facility,#{timeseries_frequency};").get
269
- end
313
+ end
314
+ if has_electricity_storage
315
+ result << OpenStudio::IdfObject.load('Output:Meter,ElectricStorage:ElectricityProduced,runperiod;').get # Used for error checking
270
316
  end
271
317
 
272
318
  # End Use/Hot Water Use/Ideal Load outputs
@@ -274,14 +320,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
274
320
  @hot_water_uses => include_timeseries_hot_water_uses,
275
321
  @ideal_system_loads => false }.each do |uses, include_timeseries|
276
322
  uses.each do |key, use|
277
- use.variables.each do |sys_id, varkey, var|
323
+ use.variables.each do |_sys_id, varkey, var|
278
324
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},runperiod;").get
279
325
  if include_timeseries
280
326
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},#{timeseries_frequency};").get
281
327
  end
282
328
  next unless use.is_a?(EndUse)
283
329
 
284
- fuel_type, end_use = key
330
+ fuel_type, _end_use = key
285
331
  if fuel_type == FT::Elec && include_hourly_electric_end_use_consumptions
286
332
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},hourly;").get
287
333
  end
@@ -302,6 +348,16 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
302
348
  result << OpenStudio::IdfObject.load("Output:Table:Monthly,#{peak_load.report},2,#{peak_load.ems_variable}_peakload_outvar,Maximum;").get
303
349
  end
304
350
 
351
+ # Unmet Hours (annual only)
352
+ @unmet_hours.each do |_key, unmet_hour|
353
+ result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{unmet_hour.ems_variable}_annual_outvar,#{unmet_hour.ems_variable},Summed,ZoneTimestep,#{unmet_hours_program.name},hr;").get
354
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{unmet_hour.ems_variable}_annual_outvar,runperiod;").get
355
+ if include_timeseries_unmet_hours
356
+ result << OpenStudio::IdfObject.load("EnergyManagementSystem:OutputVariable,#{unmet_hour.ems_variable}_timeseries_outvar,#{unmet_hour.ems_variable},Summed,ZoneTimestep,#{unmet_hours_program.name},hr;").get
357
+ result << OpenStudio::IdfObject.load("Output:Variable,*,#{unmet_hour.ems_variable}_timeseries_outvar,#{timeseries_frequency};").get
358
+ end
359
+ end
360
+
305
361
  # Component Load outputs
306
362
  @component_loads.values.each do |comp_load|
307
363
  next if comp_loads_program.nil?
@@ -324,7 +380,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
324
380
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{load.ems_variable}_timeseries_outvar,#{timeseries_frequency};").get
325
381
  end
326
382
  end
327
- load.variables.each do |sys_id, varkey, var|
383
+ load.variables.each do |_sys_id, varkey, var|
328
384
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},runperiod;").get
329
385
  if include_timeseries_total_loads
330
386
  result << OpenStudio::IdfObject.load("Output:Variable,#{varkey},#{var},#{timeseries_frequency};").get
@@ -347,6 +403,13 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
347
403
 
348
404
  result << OpenStudio::IdfObject.load("Output:Variable,#{key},Schedule Value,#{timeseries_frequency};").get
349
405
  end
406
+ # Also report thermostat setpoints
407
+ if has_heating
408
+ result << OpenStudio::IdfObject.load("Output:Variable,#{HPXML::LocationLivingSpace.upcase},Zone Thermostat Heating Setpoint Temperature,#{timeseries_frequency};").get
409
+ end
410
+ if has_cooling
411
+ result << OpenStudio::IdfObject.load("Output:Variable,#{HPXML::LocationLivingSpace.upcase},Zone Thermostat Cooling Setpoint Temperature,#{timeseries_frequency};").get
412
+ end
350
413
  end
351
414
 
352
415
  # Airflow outputs (timeseries only)
@@ -368,14 +431,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
368
431
  end
369
432
 
370
433
  # Optional output variables (timeseries only)
371
- @output_variables_requests.each do |output_variable_name, output_variable|
434
+ @output_variables_requests.each do |output_variable_name, _output_variable|
372
435
  result << OpenStudio::IdfObject.load("Output:Variable,*,#{output_variable_name},#{timeseries_frequency};").get
373
436
  end
374
437
 
375
438
  # Dual-fuel heat pump loads
376
439
  if not @object_variables_by_key[[LT, LT::Heating]].nil?
377
440
  @object_variables_by_key[[LT, LT::Heating]].each do |vals|
378
- sys_id, key, var = vals
441
+ _sys_id, key, var = vals
379
442
  result << OpenStudio::IdfObject.load("Output:Variable,#{key},#{var},runperiod;").get
380
443
  end
381
444
  end
@@ -400,19 +463,26 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
400
463
  end
401
464
 
402
465
  output_format = runner.getStringArgumentValue('output_format', user_arguments)
403
- timeseries_frequency = runner.getOptionalStringArgumentValue('timeseries_frequency', user_arguments)
404
- timeseries_frequency = timeseries_frequency.is_initialized ? timeseries_frequency.get : 'none'
466
+ if output_format == 'csv_dview'
467
+ output_format = 'csv'
468
+ use_dview_format = true
469
+ end
470
+ timeseries_frequency = runner.getStringArgumentValue('timeseries_frequency', user_arguments)
405
471
  if timeseries_frequency != 'none'
406
472
  include_timeseries_total_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_total_consumptions', user_arguments)
407
473
  include_timeseries_fuel_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_fuel_consumptions', user_arguments)
408
474
  include_timeseries_end_use_consumptions = runner.getOptionalBoolArgumentValue('include_timeseries_end_use_consumptions', user_arguments)
409
475
  include_timeseries_emissions = runner.getOptionalBoolArgumentValue('include_timeseries_emissions', user_arguments)
476
+ include_timeseries_emission_fuels = runner.getOptionalBoolArgumentValue('include_timeseries_emission_fuels', user_arguments)
477
+ include_timeseries_emission_end_uses = runner.getOptionalBoolArgumentValue('include_timeseries_emission_end_uses', user_arguments)
410
478
  include_timeseries_hot_water_uses = runner.getOptionalBoolArgumentValue('include_timeseries_hot_water_uses', user_arguments)
411
479
  include_timeseries_total_loads = runner.getOptionalBoolArgumentValue('include_timeseries_total_loads', user_arguments)
412
480
  include_timeseries_component_loads = runner.getOptionalBoolArgumentValue('include_timeseries_component_loads', user_arguments)
481
+ include_timeseries_unmet_hours = runner.getOptionalBoolArgumentValue('include_timeseries_unmet_hours', user_arguments)
413
482
  include_timeseries_zone_temperatures = runner.getOptionalBoolArgumentValue('include_timeseries_zone_temperatures', user_arguments)
414
483
  include_timeseries_airflows = runner.getOptionalBoolArgumentValue('include_timeseries_airflows', user_arguments)
415
484
  include_timeseries_weather = runner.getOptionalBoolArgumentValue('include_timeseries_weather', user_arguments)
485
+ use_timestamp_start_convention = (runner.getStringArgumentValue('timeseries_timestamp_convention', user_arguments) == 'start')
416
486
  add_timeseries_dst_column = runner.getOptionalBoolArgumentValue('add_timeseries_dst_column', user_arguments)
417
487
  add_timeseries_utc_column = runner.getOptionalBoolArgumentValue('add_timeseries_utc_column', user_arguments)
418
488
  user_output_variables = runner.getOptionalStringArgumentValue('user_output_variables', user_arguments)
@@ -421,27 +491,30 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
421
491
  include_timeseries_fuel_consumptions = include_timeseries_fuel_consumptions.is_initialized ? include_timeseries_fuel_consumptions.get : false
422
492
  include_timeseries_end_use_consumptions = include_timeseries_end_use_consumptions.is_initialized ? include_timeseries_end_use_consumptions.get : false
423
493
  include_timeseries_emissions = include_timeseries_emissions.is_initialized ? include_timeseries_emissions.get : false
494
+ include_timeseries_emission_fuels = include_timeseries_emission_fuels.is_initialized ? include_timeseries_emission_fuels.get : false
495
+ include_timeseries_emission_end_uses = include_timeseries_emission_end_uses.is_initialized ? include_timeseries_emission_end_uses.get : false
424
496
  include_timeseries_hot_water_uses = include_timeseries_hot_water_uses.is_initialized ? include_timeseries_hot_water_uses.get : false
425
497
  include_timeseries_total_loads = include_timeseries_total_loads.is_initialized ? include_timeseries_total_loads.get : false
426
498
  include_timeseries_component_loads = include_timeseries_component_loads.is_initialized ? include_timeseries_component_loads.get : false
499
+ include_timeseries_unmet_hours = include_timeseries_unmet_hours.is_initialized ? include_timeseries_unmet_hours.get : false
427
500
  include_timeseries_zone_temperatures = include_timeseries_zone_temperatures.is_initialized ? include_timeseries_zone_temperatures.get : false
428
501
  include_timeseries_airflows = include_timeseries_airflows.is_initialized ? include_timeseries_airflows.get : false
429
502
  include_timeseries_weather = include_timeseries_weather.is_initialized ? include_timeseries_weather.get : false
430
503
  user_output_variables = user_output_variables.is_initialized ? user_output_variables.get : nil
431
504
  end
505
+ generate_eri_outputs = runner.getOptionalBoolArgumentValue('generate_eri_outputs', user_arguments)
506
+ generate_eri_outputs = generate_eri_outputs.is_initialized ? generate_eri_outputs.get : false
432
507
  annual_output_file_name = runner.getOptionalStringArgumentValue('annual_output_file_name', user_arguments)
433
508
  timeseries_output_file_name = runner.getOptionalStringArgumentValue('timeseries_output_file_name', user_arguments)
434
509
 
435
510
  output_dir = File.dirname(runner.lastEpwFilePath.get.to_s)
436
511
 
437
- hpxml_path = @model.getBuilding.additionalProperties.getFeatureAsString('hpxml_path').get
438
512
  hpxml_defaults_path = @model.getBuilding.additionalProperties.getFeatureAsString('hpxml_defaults_path').get
439
513
  building_id = @model.getBuilding.additionalProperties.getFeatureAsString('building_id').get
440
514
  @hpxml = HPXML.new(hpxml_path: hpxml_defaults_path, building_id: building_id)
441
515
  HVAC.apply_shared_systems(@hpxml) # Needed for ERI shared HVAC systems
442
- @eri_design = @hpxml.header.eri_design
443
516
 
444
- setup_outputs(user_output_variables)
517
+ setup_outputs(false, user_output_variables)
445
518
 
446
519
  if not File.exist? File.join(output_dir, 'eplusout.msgpack')
447
520
  runner.registerError('Cannot find eplusout.msgpack.')
@@ -458,29 +531,22 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
458
531
  end
459
532
 
460
533
  # Set paths
461
- if not @eri_design.nil?
462
- # ERI run, store files in a particular location
463
- output_dir = File.dirname(hpxml_path)
464
- hpxml_name = File.basename(hpxml_path).gsub('.xml', '')
465
- annual_output_path = File.join(output_dir, "#{hpxml_name}.#{output_format}")
466
- timeseries_output_path = File.join(output_dir, "#{hpxml_name}_#{timeseries_frequency.capitalize}.#{output_format}")
534
+ if annual_output_file_name.is_initialized
535
+ annual_output_path = File.join(output_dir, annual_output_file_name.get)
467
536
  else
468
- if annual_output_file_name.is_initialized
469
- annual_output_path = File.join(output_dir, annual_output_file_name.get)
470
- else
471
- annual_output_path = File.join(output_dir, "results_annual.#{output_format}")
472
- end
473
- if timeseries_output_file_name.is_initialized
474
- timeseries_output_path = File.join(output_dir, timeseries_output_file_name.get)
475
- else
476
- timeseries_output_path = File.join(output_dir, "results_timeseries.#{output_format}")
477
- end
537
+ annual_output_path = File.join(output_dir, "results_annual.#{output_format}")
538
+ end
539
+ if timeseries_output_file_name.is_initialized
540
+ timeseries_output_path = File.join(output_dir, timeseries_output_file_name.get)
541
+ else
542
+ timeseries_output_path = File.join(output_dir, "results_timeseries.#{output_format}")
478
543
  end
479
544
 
480
545
  if timeseries_frequency != 'none'
481
546
  add_dst_column = (add_timeseries_dst_column.is_initialized ? add_timeseries_dst_column.get : false)
482
547
  add_utc_column = (add_timeseries_utc_column.is_initialized ? add_timeseries_utc_column.get : false)
483
- @timestamps, timestamps_dst, timestamps_utc = OutputMethods.get_timestamps(timeseries_frequency, @msgpackDataTimeseries, @hpxml, add_dst_column, add_utc_column)
548
+ @timestamps, timestamps_dst, timestamps_utc = OutputMethods.get_timestamps(@msgpackDataTimeseries, @hpxml, use_timestamp_start_convention,
549
+ add_dst_column, add_utc_column, use_dview_format, timeseries_frequency)
484
550
  end
485
551
 
486
552
  # Retrieve outputs
@@ -489,9 +555,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
489
555
  include_timeseries_fuel_consumptions,
490
556
  include_timeseries_end_use_consumptions,
491
557
  include_timeseries_emissions,
558
+ include_timeseries_emission_fuels,
559
+ include_timeseries_emission_end_uses,
492
560
  include_timeseries_hot_water_uses,
493
561
  include_timeseries_total_loads,
494
562
  include_timeseries_component_loads,
563
+ include_timeseries_unmet_hours,
495
564
  include_timeseries_zone_temperatures,
496
565
  include_timeseries_airflows,
497
566
  include_timeseries_weather)
@@ -512,23 +581,28 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
512
581
  end
513
582
 
514
583
  # Write/report results
515
- write_runperiod_output_results(runner, outputs, output_format, annual_output_path, runperiod_n_digits)
516
- report_runperiod_output_results(runner, outputs, runperiod_n_digits)
517
- write_timeseries_output_results(runner, outputs, output_format,
518
- timeseries_output_path,
519
- timeseries_frequency,
520
- include_timeseries_total_consumptions,
521
- include_timeseries_fuel_consumptions,
522
- include_timeseries_end_use_consumptions,
523
- include_timeseries_emissions,
524
- include_timeseries_hot_water_uses,
525
- include_timeseries_total_loads,
526
- include_timeseries_component_loads,
527
- include_timeseries_zone_temperatures,
528
- include_timeseries_airflows,
529
- include_timeseries_weather,
530
- timestamps_dst,
531
- timestamps_utc)
584
+ report_runperiod_output_results(runner, outputs, output_format, annual_output_path, runperiod_n_digits, generate_eri_outputs)
585
+ report_timeseries_output_results(runner, outputs, output_format,
586
+ timeseries_output_path,
587
+ timeseries_frequency,
588
+ include_timeseries_total_consumptions,
589
+ include_timeseries_fuel_consumptions,
590
+ include_timeseries_end_use_consumptions,
591
+ include_timeseries_emissions,
592
+ include_timeseries_emission_fuels,
593
+ include_timeseries_emission_end_uses,
594
+ include_timeseries_hot_water_uses,
595
+ include_timeseries_total_loads,
596
+ include_timeseries_component_loads,
597
+ include_timeseries_unmet_hours,
598
+ include_timeseries_zone_temperatures,
599
+ include_timeseries_airflows,
600
+ include_timeseries_weather,
601
+ add_dst_column,
602
+ add_utc_column,
603
+ timestamps_dst,
604
+ timestamps_utc,
605
+ use_dview_format)
532
606
 
533
607
  return true
534
608
  end
@@ -538,9 +612,12 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
538
612
  include_timeseries_fuel_consumptions,
539
613
  include_timeseries_end_use_consumptions,
540
614
  include_timeseries_emissions,
615
+ include_timeseries_emission_fuels,
616
+ include_timeseries_emission_end_uses,
541
617
  include_timeseries_hot_water_uses,
542
618
  include_timeseries_total_loads,
543
619
  include_timeseries_component_loads,
620
+ include_timeseries_unmet_hours,
544
621
  include_timeseries_zone_temperatures,
545
622
  include_timeseries_airflows,
546
623
  include_timeseries_weather)
@@ -551,7 +628,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
551
628
  # TODO: This could be removed if we could account for DSE inside EnergyPlus.
552
629
  if not @emissions.empty?
553
630
  include_hourly_electric_end_use_consumptions = true # For annual Cambium calculation
554
- if include_timeseries_emissions
631
+ if include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
555
632
  include_timeseries_fuel_consumptions = true
556
633
  end
557
634
  end
@@ -563,15 +640,16 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
563
640
  end
564
641
 
565
642
  # Fuel Uses
566
- @fuels.each do |fuel_type, fuel|
643
+ @fuels.each do |_fuel_type, fuel|
567
644
  fuel.annual_output = get_report_meter_data_annual(fuel.meters)
568
- if include_timeseries_fuel_consumptions
569
- fuel.timeseries_output = get_report_meter_data_timeseries(fuel.meters, UnitConversions.convert(1.0, 'J', fuel.timeseries_units), 0, timeseries_frequency)
570
- end
645
+
646
+ next unless include_timeseries_fuel_consumptions
647
+
648
+ fuel.timeseries_output = get_report_meter_data_timeseries(fuel.meters, UnitConversions.convert(1.0, 'J', fuel.timeseries_units), 0, timeseries_frequency)
571
649
  end
572
650
 
573
651
  # Peak Electricity Consumption
574
- @peak_fuels.each do |key, peak_fuel|
652
+ @peak_fuels.each do |_key, peak_fuel|
575
653
  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)
576
654
  end
577
655
 
@@ -598,7 +676,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
598
676
  end
599
677
 
600
678
  # Component Loads
601
- @component_loads.each do |key, comp_load|
679
+ @component_loads.each do |_key, comp_load|
602
680
  comp_load.annual_output = get_report_variable_data_annual(['EMS'], ["#{comp_load.ems_variable}_annual_outvar"])
603
681
  if include_timeseries_component_loads
604
682
  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)
@@ -606,17 +684,15 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
606
684
  end
607
685
 
608
686
  # Unmet Hours
609
- @unmet_hours.each do |key, unmet_hour|
610
- if (key == UHT::Heating && @hpxml.total_fraction_heat_load_served <= 0) ||
611
- (key == UHT::Cooling && @hpxml.total_fraction_cool_load_served <= 0)
612
- next # Don't report unmet hours if there is no heating/cooling system
687
+ @unmet_hours.each do |_key, unmet_hour|
688
+ unmet_hour.annual_output = get_report_variable_data_annual(['EMS'], ["#{unmet_hour.ems_variable}_annual_outvar"], 1.0)
689
+ if include_timeseries_unmet_hours
690
+ unmet_hour.timeseries_output = get_report_variable_data_timeseries(['EMS'], ["#{unmet_hour.ems_variable}_timeseries_outvar"], 1.0, 0, timeseries_frequency)
613
691
  end
614
-
615
- unmet_hour.annual_output = get_tabular_data_value('SystemSummary', 'Entire Facility', 'Time Setpoint Not Met', [HPXML::LocationLivingSpace.upcase], unmet_hour.col_name, unmet_hour.annual_units)
616
692
  end
617
693
 
618
694
  # Ideal system loads (expected fraction of loads that are not met by partial HVAC (e.g., room AC that meets 30% of load))
619
- @ideal_system_loads.each do |load_type, ideal_load|
695
+ @ideal_system_loads.each do |_load_type, ideal_load|
620
696
  ideal_load.variables.map { |v| v[0] }.uniq.each do |sys_id|
621
697
  keys = ideal_load.variables.select { |v| v[0] == sys_id }.map { |v| v[1] }
622
698
  vars = ideal_load.variables.select { |v| v[0] == sys_id }.map { |v| v[2] }
@@ -626,30 +702,48 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
626
702
  end
627
703
 
628
704
  # Peak Building Space Heating/Cooling Loads (total heating/cooling energy delivered including backup ideal air system)
629
- @peak_loads.each do |load_type, peak_load|
630
- peak_load.annual_output = UnitConversions.convert(get_tabular_data_value(peak_load.report.upcase, 'EMS', 'Custom Monthly Report', ['Maximum of Months'], "#{peak_load.ems_variable.upcase}_PEAKLOAD_OUTVAR {Maximum}", 'W'), 'Wh', peak_load.annual_units)
705
+ @peak_loads.each do |_load_type, peak_load|
706
+ peak_load.annual_output = UnitConversions.convert(get_tabular_data_value(peak_load.report.upcase, 'EMS', 'Custom Monthly Report', ['Maximum of Months'], "#{peak_load.ems_variable.upcase}_PEAKLOAD_OUTVAR {Maximum}", 'W'), 'W', peak_load.annual_units)
631
707
  end
632
708
 
633
709
  # End Uses
634
710
  @end_uses.each do |key, end_use|
635
- fuel_type, end_use_type = key
711
+ fuel_type, _end_use_type = key
636
712
 
637
713
  end_use.variables.map { |v| v[0] }.uniq.each do |sys_id|
638
714
  keys = end_use.variables.select { |v| v[0] == sys_id }.map { |v| v[1] }
639
715
  vars = end_use.variables.select { |v| v[0] == sys_id }.map { |v| v[2] }
640
716
 
641
- end_use.annual_output_by_system[sys_id] = get_report_variable_data_annual(keys, vars, is_negative: end_use.is_negative)
717
+ 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))
718
+
642
719
  if include_timeseries_end_use_consumptions
643
- 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)
720
+ 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))
644
721
  end
645
722
  if include_hourly_electric_end_use_consumptions && fuel_type == FT::Elec
646
- 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)
723
+ 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))
647
724
  end
648
725
  end
649
726
  end
650
727
 
728
+ # Disaggregate 8760 GSHP shared pump energy into heating vs cooling by
729
+ # applying proportionally to the GSHP heating & cooling fan/pump energy use.
730
+ gshp_shared_loop_end_use = @end_uses[[FT::Elec, 'TempGSHPSharedPump']]
731
+ htg_fan_pump_end_use = @end_uses[[FT::Elec, EUT::HeatingFanPump]]
732
+ clg_fan_pump_end_use = @end_uses[[FT::Elec, EUT::CoolingFanPump]]
733
+ gshp_shared_loop_end_use.annual_output_by_system.keys.each do |sys_id|
734
+ # Calculate heating & cooling fan/pump end use multiplier
735
+ htg_energy = htg_fan_pump_end_use.annual_output_by_system[sys_id]
736
+ clg_energy = clg_fan_pump_end_use.annual_output_by_system[sys_id]
737
+ shared_pump_energy = gshp_shared_loop_end_use.annual_output_by_system[sys_id]
738
+ energy_multiplier = (htg_energy + clg_energy + shared_pump_energy) / (htg_energy + clg_energy)
739
+ # Apply multiplier
740
+ apply_multiplier_to_output(htg_fan_pump_end_use, nil, sys_id, energy_multiplier)
741
+ apply_multiplier_to_output(clg_fan_pump_end_use, nil, sys_id, energy_multiplier)
742
+ end
743
+ @end_uses.delete([FT::Elec, 'TempGSHPSharedPump'])
744
+
651
745
  # Hot Water Uses
652
- @hot_water_uses.each do |hot_water_type, hot_water|
746
+ @hot_water_uses.each do |_hot_water_type, hot_water|
653
747
  hot_water.variables.map { |v| v[0] }.uniq.each do |sys_id|
654
748
  keys = hot_water.variables.select { |v| v[0] == sys_id }.map { |v| v[1] }
655
749
  vars = hot_water.variables.select { |v| v[0] == sys_id }.map { |v| v[2] }
@@ -747,11 +841,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
747
841
  end
748
842
 
749
843
  # Total/Net Electricity (Net includes, e.g., PV and generators)
750
- 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
844
+ 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
751
845
  outputs[:elec_net_annual] = @fuels[FT::Elec].annual_output.to_f + outputs[:elec_prod_annual]
752
846
  if include_timeseries_fuel_consumptions
753
847
  outputs[:elec_prod_timeseries] = [0.0] * @timestamps.size # Negative values
754
- @end_uses.select { |k, eu| k[0] == FT::Elec && eu.is_negative && eu.timeseries_output.size > 0 }.each do |key, end_use|
848
+ @end_uses.select { |k, eu| k[0] == FT::Elec && eu.is_negative && eu.timeseries_output.size > 0 }.each do |_key, end_use|
755
849
  outputs[:elec_prod_timeseries] = outputs[:elec_prod_timeseries].zip(end_use.timeseries_output).map { |x, y| x + y }
756
850
  end
757
851
  outputs[:elec_net_timeseries] = @fuels[FT::Elec].timeseries_output.zip(outputs[:elec_prod_timeseries]).map { |x, y| x + y }
@@ -759,7 +853,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
759
853
 
760
854
  # Total/Net Energy (Net includes, e.g., PV and generators)
761
855
  @totals[TE::Total].annual_output = 0.0
762
- @fuels.each do |fuel_type, fuel|
856
+ @fuels.each do |_fuel_type, fuel|
763
857
  @totals[TE::Total].annual_output += fuel.annual_output
764
858
  next unless include_timeseries_total_consumptions && fuel.timeseries_output.sum != 0.0
765
859
 
@@ -800,18 +894,25 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
800
894
  @zone_temps[scheduled_temperature_name].timeseries_units = 'F'
801
895
  @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)
802
896
  end
897
+ { 'Heating Setpoint' => 'Zone Thermostat Heating Setpoint Temperature',
898
+ 'Cooling Setpoint' => 'Zone Thermostat Cooling Setpoint Temperature' }.each do |sp_name, sp_var|
899
+ @zone_temps[sp_name] = ZoneTemp.new
900
+ @zone_temps[sp_name].name = "Temperature: #{sp_name}"
901
+ @zone_temps[sp_name].timeseries_units = 'F'
902
+ @zone_temps[sp_name].timeseries_output = get_report_variable_data_timeseries([HPXML::LocationLivingSpace.upcase], [sp_var], 9.0 / 5.0, 32.0, timeseries_frequency)
903
+ end
803
904
  end
804
905
 
805
906
  # Airflows
806
907
  if include_timeseries_airflows
807
- @airflows.each do |airflow_type, airflow|
908
+ @airflows.each do |_airflow_type, airflow|
808
909
  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)
809
910
  end
810
911
  end
811
912
 
812
913
  # Weather
813
914
  if include_timeseries_weather
814
- @weather.each do |weather_type, weather_data|
915
+ @weather.each do |_weather_type, weather_data|
815
916
  if weather_data.timeseries_units == 'F'
816
917
  unit_conv = 9.0 / 5.0
817
918
  unit_adder = 32.0
@@ -824,8 +925,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
824
925
  end
825
926
 
826
927
  @output_variables = {}
827
- @output_variables_requests.each do |output_variable_name, output_variable|
828
- key_values, units = get_report_variable_data_timeseries_key_values_and_units(timeseries_frequency, output_variable_name)
928
+ @output_variables_requests.each do |output_variable_name, _output_variable|
929
+ key_values, units = get_report_variable_data_timeseries_key_values_and_units(output_variable_name)
829
930
  runner.registerWarning("Request for output variable '#{output_variable_name}' returned no key values.") if key_values.empty?
830
931
  key_values.each do |key_value|
831
932
  @output_variables[[output_variable_name, key_value]] = OutputVariable.new
@@ -839,25 +940,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
839
940
  if not @emissions.empty?
840
941
  kwh_to_mwh = UnitConversions.convert(1.0, 'kWh', 'MWh')
841
942
 
842
- hourly_elec_net = nil
843
- @end_uses.each do |key, end_use|
844
- next unless end_use.hourly_output.size > 0
845
-
846
- hourly_elec_net = [0.0] * end_use.hourly_output.size if hourly_elec_net.nil?
847
- hourly_elec_net = hourly_elec_net.zip(end_use.hourly_output).map { |x, y| x + y * kwh_to_mwh }
848
- end
849
- if include_timeseries_emissions
850
- if timeseries_frequency == 'timestep' && @hpxml.header.timestep != 60
851
- timeseries_elec_net = outputs[:elec_net_timeseries].map { |x| x * kwh_to_mwh }
852
- else
853
- # Need to perform calculations hourly at a minimum
854
- timeseries_elec_net = hourly_elec_net.dup
855
- end
856
- end
857
-
858
943
  # Calculate for each scenario
859
944
  @hpxml.header.emissions_scenarios.each do |scenario|
860
945
  key = [scenario.emissions_type, scenario.name]
946
+
947
+ # Get hourly electricity factors
861
948
  if not scenario.elec_schedule_filepath.nil?
862
949
  # Obtain Cambium hourly factors for the simulation run period
863
950
  num_header_rows = scenario.elec_schedule_number_of_header_rows
@@ -877,62 +964,85 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
877
964
  sim_start_day_of_year, sim_end_day_of_year, sim_start_hour, sim_end_hour = get_sim_times_of_year(year)
878
965
  hourly_elec_factors = hourly_elec_factors[sim_start_hour..sim_end_hour]
879
966
 
880
- if hourly_elec_net.size == hourly_elec_factors[sim_start_hour..sim_end_hour].size + 24
881
- # Use leap-year for calculations
882
- year = 2000
883
- sim_start_day_of_year, sim_end_day_of_year, sim_start_hour, sim_end_hour = get_sim_times_of_year(year)
884
- # Duplicate Feb 28 Cambium values for Feb 29
885
- hourly_elec_factors = hourly_elec_factors[0..1415] + hourly_elec_factors[1392..1415] + hourly_elec_factors[1416..8759]
886
- end
887
- hourly_elec_factors = hourly_elec_factors[sim_start_hour..sim_end_hour] # Trim to sim period
967
+ # Calculate annual/timeseries emissions for each end use
968
+ @end_uses.each do |eu_key, end_use|
969
+ fuel_type, _end_use_type = eu_key
970
+ next unless fuel_type == FT::Elec
971
+ next unless end_use.hourly_output.size > 0
888
972
 
889
- fail 'Unexpected failure for emissions calculations.' if hourly_elec_factors.size != hourly_elec_net.size
973
+ hourly_elec = end_use.hourly_output
974
+
975
+ if hourly_elec.size == hourly_elec_factors[sim_start_hour..sim_end_hour].size + 24
976
+ # Use leap-year for calculations
977
+ year = 2000
978
+ sim_start_day_of_year, sim_end_day_of_year, sim_start_hour, sim_end_hour = get_sim_times_of_year(year)
979
+ # Duplicate Feb 28 Cambium values for Feb 29
980
+ hourly_elec_factors = hourly_elec_factors[0..1415] + hourly_elec_factors[1392..1415] + hourly_elec_factors[1416..8759]
981
+ end
982
+ hourly_elec_factors = hourly_elec_factors[sim_start_hour..sim_end_hour] # Trim to sim period
983
+
984
+ fail 'Unexpected failure for emissions calculations.' if hourly_elec_factors.size != hourly_elec.size
985
+
986
+ # Calculate annual emissions for end use
987
+ if scenario.elec_units == HPXML::EmissionsScenario::UnitsKgPerMWh
988
+ elec_units_mult = UnitConversions.convert(1.0, 'kg', 'lbm')
989
+ elsif scenario.elec_units == HPXML::EmissionsScenario::UnitsLbPerMWh
990
+ elec_units_mult = 1.0
991
+ end
992
+ @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
993
+
994
+ next unless include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
995
+
996
+ # Calculate timeseries emissions for end use
997
+
998
+ if timeseries_frequency == 'timestep' && @hpxml.header.timestep != 60
999
+ timeseries_elec = nil
1000
+ end_use.timeseries_output_by_system.each do |_sys_id, timeseries_output|
1001
+ timeseries_elec = [0.0] * timeseries_output.size if timeseries_elec.nil?
1002
+ timeseries_elec = timeseries_elec.zip(timeseries_output.map { |x| x * kwh_to_mwh }).map { |x, y| x + y }
1003
+ end
1004
+ else
1005
+ # Need to perform calculations hourly at a minimum
1006
+ timeseries_elec = end_use.hourly_output.map { |x| x * kwh_to_mwh }
1007
+ end
890
1008
 
891
- # Calculate annual emissions for net electricity
892
- if scenario.elec_units == HPXML::EmissionsScenario::UnitsKgPerMWh
893
- elec_units_mult = UnitConversions.convert(1.0, 'kg', 'lbm')
894
- elsif scenario.elec_units == HPXML::EmissionsScenario::UnitsLbPerMWh
895
- elec_units_mult = 1.0
896
- end
897
- @emissions[key].annual_output_by_fuel[FT::Elec] = hourly_elec_net.zip(hourly_elec_factors).map { |x, y| x * y * elec_units_mult }.sum
898
- if include_timeseries_emissions
899
- # Calculate hourly emissions for net electricity
900
1009
  if timeseries_frequency == 'timestep'
901
1010
  n_timesteps_per_hour = Integer(60.0 / @hpxml.header.timestep)
902
1011
  timeseries_elec_factors = hourly_elec_factors.flat_map { |y| [y] * n_timesteps_per_hour }
903
1012
  else
904
1013
  timeseries_elec_factors = hourly_elec_factors.dup
905
1014
  end
906
- fail 'Unexpected failure for emissions calculations.' if timeseries_elec_factors.size != timeseries_elec_net.size
1015
+ fail 'Unexpected failure for emissions calculations.' if timeseries_elec_factors.size != timeseries_elec.size
907
1016
 
908
- @emissions[key].timeseries_output_by_fuel[FT::Elec] = timeseries_elec_net.zip(timeseries_elec_factors).map { |n, f| n * f * elec_units_mult }
1017
+ @emissions[key].timeseries_output_by_end_use[eu_key] = timeseries_elec.zip(timeseries_elec_factors).map { |n, f| n * f * elec_units_mult }
909
1018
 
910
1019
  # Aggregate up from hourly to the desired timeseries frequency
911
- if ['daily', 'monthly'].include? timeseries_frequency
912
- if timeseries_frequency == 'daily'
913
- n_hours_per_period = [24] * (sim_end_day_of_year - sim_start_day_of_year + 1)
914
- elsif timeseries_frequency == 'monthly'
915
- n_days_per_month = Constants.NumDaysInMonths(year)
916
- n_days_per_period = n_days_per_month[@hpxml.header.sim_begin_month - 1..@hpxml.header.sim_end_month - 1]
917
- n_days_per_period[0] -= @hpxml.header.sim_begin_day - 1
918
- n_days_per_period[-1] = @hpxml.header.sim_end_day
919
- n_hours_per_period = n_days_per_period.map { |x| x * 24 }
920
- end
921
- fail 'Unexpected failure for emissions calculations.' if n_hours_per_period.sum != @emissions[key].timeseries_output_by_fuel[FT::Elec].size
1020
+ next unless ['daily', 'monthly'].include? timeseries_frequency
1021
+
1022
+ if timeseries_frequency == 'daily'
1023
+ n_hours_per_period = [24] * (sim_end_day_of_year - sim_start_day_of_year + 1)
1024
+ elsif timeseries_frequency == 'monthly'
1025
+ n_days_per_month = Constants.NumDaysInMonths(year)
1026
+ n_days_per_period = n_days_per_month[@hpxml.header.sim_begin_month - 1..@hpxml.header.sim_end_month - 1]
1027
+ n_days_per_period[0] -= @hpxml.header.sim_begin_day - 1
1028
+ n_days_per_period[-1] = @hpxml.header.sim_end_day
1029
+ n_hours_per_period = n_days_per_period.map { |x| x * 24 }
1030
+ end
1031
+ fail 'Unexpected failure for emissions calculations.' if n_hours_per_period.sum != @emissions[key].timeseries_output_by_end_use[eu_key].size
922
1032
 
923
- timeseries_output = []
924
- start_hour = 0
925
- n_hours_per_period.each do |n_hours|
926
- timeseries_output << @emissions[key].timeseries_output_by_fuel[FT::Elec][start_hour..start_hour + n_hours - 1].sum()
927
- start_hour += n_hours
928
- end
929
- @emissions[key].timeseries_output_by_fuel[FT::Elec] = timeseries_output
1033
+ timeseries_output = []
1034
+ start_hour = 0
1035
+ n_hours_per_period.each do |n_hours|
1036
+ timeseries_output << @emissions[key].timeseries_output_by_end_use[eu_key][start_hour..start_hour + n_hours - 1].sum()
1037
+ start_hour += n_hours
930
1038
  end
1039
+ @emissions[key].timeseries_output_by_end_use[eu_key] = timeseries_output
931
1040
  end
932
1041
 
933
1042
  # Calculate emissions for fossil fuels
934
- @fuels.each do |fuel_type, fuel|
935
- next if [FT::Elec].include? fuel_type
1043
+ @end_uses.each do |eu_key, end_use|
1044
+ fuel_type, _end_use_type = eu_key
1045
+ next if fuel_type == FT::Elec
936
1046
 
937
1047
  fuel_map = { FT::Gas => [scenario.natural_gas_units, scenario.natural_gas_value],
938
1048
  FT::Propane => [scenario.propane_units, scenario.propane_value],
@@ -942,7 +1052,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
942
1052
  FT::WoodPellets => [scenario.wood_pellets_units, scenario.wood_pellets_value] }
943
1053
  fuel_units, fuel_factor = fuel_map[fuel_type]
944
1054
  if fuel_factor.nil?
945
- if fuel.annual_output != 0
1055
+ if end_use.annual_output != 0
946
1056
  runner.registerWarning("No emissions factor found for Scenario=#{scenario.name}, Type=#{scenario.emissions_type}, Fuel=#{fuel_type}.")
947
1057
  end
948
1058
  fuel_factor = 0.0
@@ -953,13 +1063,31 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
953
1063
  fuel_units_mult = 1.0
954
1064
  end
955
1065
 
956
- @emissions[key].annual_output_by_fuel[fuel_type] = UnitConversions.convert(fuel.annual_output, fuel.annual_units, 'MBtu') * fuel_factor * fuel_units_mult
957
- next unless include_timeseries_emissions
1066
+ @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
1067
+ next unless include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
1068
+
1069
+ fuel_to_mbtu = UnitConversions.convert(1.0, end_use.timeseries_units, 'MBtu')
1070
+
1071
+ end_use.timeseries_output_by_system.each do |_sys_id, timeseries_output|
1072
+ @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?
1073
+ @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 }
1074
+ end
1075
+ end
1076
+
1077
+ # Roll up end use emissions to fuel emissions
1078
+ @fuels.each do |fuel_type, _fuel|
1079
+ @emissions[key].annual_output_by_fuel[fuel_type] = 0.0
1080
+ @emissions[key].annual_output_by_end_use.keys.each do |eu_key|
1081
+ next unless eu_key[0] == fuel_type
1082
+ next if @emissions[key].annual_output_by_end_use[eu_key] == 0
1083
+
1084
+ @emissions[key].annual_output_by_fuel[fuel_type] += @emissions[key].annual_output_by_end_use[eu_key]
958
1085
 
959
- fuel_to_mbtu = UnitConversions.convert(1.0, fuel.timeseries_units, 'MBtu')
960
- fail 'Unexpected failure for emissions calculations.' if fuel.timeseries_output.size != @emissions[key].timeseries_output_by_fuel[FT::Elec].size
1086
+ next unless include_timeseries_emissions || include_timeseries_emission_end_uses || include_timeseries_emission_fuels
961
1087
 
962
- @emissions[key].timeseries_output_by_fuel[fuel_type] = fuel.timeseries_output.map { |f| f * fuel_to_mbtu * fuel_factor * fuel_units_mult }
1088
+ @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?
1089
+ @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 }
1090
+ end
963
1091
  end
964
1092
 
965
1093
  # Sum individual fuel results for total
@@ -967,7 +1095,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
967
1095
  next unless not @emissions[key].timeseries_output_by_fuel.empty?
968
1096
 
969
1097
  @emissions[key].timeseries_output = @emissions[key].timeseries_output_by_fuel.first[1]
970
- @emissions[key].timeseries_output_by_fuel.each_with_index do |(fuel, timeseries_output), i|
1098
+ @emissions[key].timeseries_output_by_fuel.each_with_index do |(_fuel, timeseries_output), i|
971
1099
  next if i == 0
972
1100
 
973
1101
  @emissions[key].timeseries_output = @emissions[key].timeseries_output.zip(timeseries_output).map { |x, y| x + y }
@@ -987,7 +1115,20 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
987
1115
  end
988
1116
 
989
1117
  def check_for_errors(runner, outputs)
1118
+ tol = 0.1
1119
+
1120
+ # ElectricityProduced:Facility contains:
1121
+ # - Generator Produced DC Electricity Energy
1122
+ # - Inverter Conversion Loss Decrement Energy
1123
+ # - Electric Storage Production Decrement Energy
1124
+ # - Electric Storage Discharge Energy
1125
+ # - Converter Electricity Loss Decrement Energy (should always be zero since efficiency=1.0)
1126
+ # ElectricStorage:ElectricityProduced contains:
1127
+ # - Electric Storage Production Decrement Energy
1128
+ # - Electric Storage Discharge Energy
1129
+ # So, we need to subtract ElectricStorage:ElectricityProduced from ElectricityProduced:Facility
990
1130
  meter_elec_produced = -1 * get_report_meter_data_annual(['ElectricityProduced:Facility'])
1131
+ meter_elec_produced += get_report_meter_data_annual(['ElectricStorage:ElectricityProduced'])
991
1132
 
992
1133
  # Check if simulation successful
993
1134
  all_total = @fuels.values.map { |x| x.annual_output.to_f }.sum(0.0)
@@ -995,22 +1136,26 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
995
1136
  if all_total == 0
996
1137
  runner.registerError('Simulation unsuccessful.')
997
1138
  return false
1139
+ elsif all_total.infinite?
1140
+ runner.registerError('Simulation used infinite energy; double-check inputs.')
1141
+ return false
998
1142
  end
999
1143
 
1000
1144
  # Check sum of electricity produced end use outputs match total output from meter
1001
- if (outputs[:elec_prod_annual] - meter_elec_produced).abs > 0.1
1145
+ if (outputs[:elec_prod_annual] - meter_elec_produced).abs > tol
1002
1146
  runner.registerError("#{FT::Elec} produced category end uses (#{outputs[:elec_prod_annual].round(3)}) do not sum to total (#{meter_elec_produced.round(3)}).")
1003
1147
  return false
1004
1148
  end
1005
1149
 
1006
1150
  # Check sum of end use outputs match fuel outputs from meters
1007
1151
  @fuels.keys.each do |fuel_type|
1008
- sum_categories = @end_uses.select { |k, eu| k[0] == fuel_type }.map { |k, eu| eu.annual_output.to_f }.sum(0.0)
1152
+ sum_categories = @end_uses.select { |k, _eu| k[0] == fuel_type }.map { |_k, eu| eu.annual_output.to_f }.sum(0.0)
1009
1153
  meter_fuel_total = @fuels[fuel_type].annual_output.to_f
1010
1154
  if fuel_type == FT::Elec
1011
1155
  meter_fuel_total += meter_elec_produced
1012
1156
  end
1013
- if (sum_categories - meter_fuel_total).abs > 0.1
1157
+
1158
+ if (sum_categories - meter_fuel_total).abs > tol
1014
1159
  runner.registerError("#{fuel_type} category end uses (#{sum_categories.round(3)}) do not sum to total (#{meter_fuel_total.round(3)}).")
1015
1160
  return false
1016
1161
  end
@@ -1028,7 +1173,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1028
1173
 
1029
1174
  sum_timeseries = UnitConversions.convert(obj.timeseries_output.sum(0.0), obj.timeseries_units, obj.annual_units)
1030
1175
  annual_total = obj.annual_output.to_f
1031
- if (annual_total - sum_timeseries).abs > 0.1
1176
+ if (annual_total - sum_timeseries).abs > tol
1032
1177
  runner.registerError("Timeseries outputs (#{sum_timeseries.round(3)}) do not sum to annual output (#{annual_total.round(3)}) for #{output_type}: #{key}.")
1033
1178
  return false
1034
1179
  end
@@ -1038,11 +1183,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1038
1183
  return true
1039
1184
  end
1040
1185
 
1041
- def write_runperiod_output_results(runner, outputs, output_format, annual_output_path, n_digits)
1186
+ def report_runperiod_output_results(runner, outputs, output_format, annual_output_path, n_digits, generate_eri_outputs)
1042
1187
  line_break = nil
1043
1188
 
1044
1189
  results_out = []
1045
- @totals.each do |energy_type, total_energy|
1190
+ @totals.each do |_energy_type, total_energy|
1046
1191
  results_out << ["#{total_energy.name} (#{total_energy.annual_units})", total_energy.annual_output.to_f.round(n_digits)]
1047
1192
  end
1048
1193
  results_out << [line_break]
@@ -1053,48 +1198,60 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1053
1198
  end
1054
1199
  end
1055
1200
  results_out << [line_break]
1056
- @end_uses.each do |key, end_use|
1201
+ @end_uses.each do |_key, end_use|
1057
1202
  results_out << ["#{end_use.name} (#{end_use.annual_units})", end_use.annual_output.to_f.round(n_digits)]
1058
1203
  end
1059
1204
  if not @emissions.empty?
1060
1205
  results_out << [line_break]
1061
- # Include total and disaggregated by fuel
1062
- @emissions.each do |scenario_key, emission|
1063
- results_out << ["#{emission.name} (#{emission.annual_units})", emission.annual_output.to_f.round(2)]
1206
+ @emissions.each do |_scenario_key, emission|
1207
+ # Emissions total
1208
+ results_out << ["#{emission.name}: Total (#{emission.annual_units})", emission.annual_output.to_f.round(2)]
1209
+ # Emissions by fuel
1064
1210
  emission.annual_output_by_fuel.each do |fuel, annual_output|
1065
- results_out << ["#{emission.name.gsub(': Total', ': ' + fuel)} (#{emission.annual_units})", emission.annual_output_by_fuel[fuel].to_f.round(2)]
1211
+ next if annual_output.to_f == 0
1212
+
1213
+ results_out << ["#{emission.name}: #{fuel}: Total (#{emission.annual_units})", annual_output.to_f.round(2)]
1214
+ # Emissions by end use
1215
+ emission.annual_output_by_end_use.each do |key, eu_annual_output|
1216
+ fuel_type, end_use_type = key
1217
+ next unless fuel_type == fuel
1218
+ next if eu_annual_output.to_f == 0
1219
+
1220
+ results_out << ["#{emission.name}: #{fuel_type}: #{end_use_type} (#{emission.annual_units})", eu_annual_output.to_f.round(2)]
1221
+ end
1066
1222
  end
1067
1223
  end
1068
1224
  end
1069
1225
  results_out << [line_break]
1070
- @loads.each do |load_type, load|
1226
+ @loads.each do |_load_type, load|
1071
1227
  results_out << ["#{load.name} (#{load.annual_units})", load.annual_output.to_f.round(n_digits)]
1072
1228
  end
1073
1229
  results_out << [line_break]
1074
- @unmet_hours.each do |load_type, unmet_hour|
1230
+ @unmet_hours.each do |_load_type, unmet_hour|
1075
1231
  results_out << ["#{unmet_hour.name} (#{unmet_hour.annual_units})", unmet_hour.annual_output.to_f.round(n_digits)]
1076
1232
  end
1077
1233
  results_out << [line_break]
1078
- @peak_fuels.each do |key, peak_fuel|
1234
+ @peak_fuels.each do |_key, peak_fuel|
1079
1235
  results_out << ["#{peak_fuel.name} (#{peak_fuel.annual_units})", peak_fuel.annual_output.to_f.round(n_digits - 2)]
1080
1236
  end
1081
1237
  results_out << [line_break]
1082
- @peak_loads.each do |load_type, peak_load|
1238
+ @peak_loads.each do |_load_type, peak_load|
1083
1239
  results_out << ["#{peak_load.name} (#{peak_load.annual_units})", peak_load.annual_output.to_f.round(n_digits)]
1084
1240
  end
1085
1241
  if @component_loads.values.map { |load| load.annual_output.to_f }.sum != 0 # Skip if component loads not calculated
1086
1242
  results_out << [line_break]
1087
- @component_loads.each do |load_type, load|
1243
+ @component_loads.each do |_load_type, load|
1088
1244
  results_out << ["#{load.name} (#{load.annual_units})", load.annual_output.to_f.round(n_digits)]
1089
1245
  end
1090
1246
  end
1091
1247
  results_out << [line_break]
1092
- @hot_water_uses.each do |hot_water_type, hot_water|
1248
+ @hot_water_uses.each do |_hot_water_type, hot_water|
1093
1249
  results_out << ["#{hot_water.name} (#{hot_water.annual_units})", hot_water.annual_output.to_f.round(n_digits - 2)]
1094
1250
  end
1095
1251
 
1096
- if not @eri_design.nil?
1097
- results_out = append_eri_results(outputs, results_out, line_break)
1252
+ results_out = append_sizing_results(results_out, line_break)
1253
+ if generate_eri_outputs
1254
+ results_out = append_eri_results(results_out, line_break)
1098
1255
  end
1099
1256
 
1100
1257
  if ['csv'].include? output_format
@@ -1117,54 +1274,88 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1117
1274
  end
1118
1275
  end
1119
1276
  runner.registerInfo("Wrote annual output results to #{annual_output_path}.")
1120
- end
1121
1277
 
1122
- def report_runperiod_output_results(runner, outputs, n_digits)
1123
- all_outputs = []
1124
- all_outputs << @totals
1125
- all_outputs << @fuels
1126
- all_outputs << @end_uses
1127
- all_outputs << @emissions
1128
- all_outputs << @loads
1129
- all_outputs << @unmet_hours
1130
- all_outputs << @peak_fuels
1131
- all_outputs << @peak_loads
1132
- if @component_loads.values.map { |load| load.annual_output.to_f }.sum != 0 # Skip if component loads not calculated
1133
- all_outputs << @component_loads
1278
+ results_out.each do |name, value|
1279
+ next if name.nil? || value.nil?
1280
+
1281
+ name = OpenStudio::toUnderscoreCase(name).chomp('_')
1282
+
1283
+ runner.registerValue(name, value)
1284
+ runner.registerInfo("Registering #{value} for #{name}.")
1134
1285
  end
1135
- all_outputs << @hot_water_uses
1286
+ end
1136
1287
 
1137
- all_outputs.each do |o|
1138
- o.each do |key, obj|
1139
- output_name = OpenStudio::toUnderscoreCase(get_runner_output_name(obj))
1140
- output_val = obj.annual_output.to_f.round(n_digits)
1141
- runner.registerValue(output_name, output_val)
1142
- runner.registerInfo("Registering #{output_val} for #{output_name}.")
1143
-
1144
- if obj.is_a?(Emission)
1145
- # Include total and disaggregated by fuel
1146
- obj.annual_output_by_fuel.each do |fuel, annual_output|
1147
- output_name = OpenStudio::toUnderscoreCase(get_runner_output_name(obj).gsub(': Total', ': ' + fuel))
1148
- output_val = annual_output.to_f.round(n_digits)
1149
- runner.registerValue(output_name, output_val)
1150
- runner.registerInfo("Registering #{output_val} for #{output_name}.")
1151
- end
1152
- elsif key == FT::Elec && obj.is_a?(Fuel)
1153
- # Also add Net Electricity
1154
- output_name = OpenStudio::toUnderscoreCase('Fuel Use: Electricity: Net (MBtu)')
1155
- output_val = outputs[:elec_net_annual].round(n_digits)
1156
- runner.registerValue(output_name, output_val)
1157
- runner.registerInfo("Registering #{output_val} for #{output_name}.")
1288
+ def get_runner_output_name(name, annual_units)
1289
+ return "#{name} #{annual_units}"
1290
+ end
1291
+
1292
+ def append_sizing_results(results_out, line_break)
1293
+ # Summary HVAC capacities
1294
+ htg_cap, clg_cap, hp_backup_cap = 0.0, 0.0, 0.0
1295
+ @hpxml.hvac_systems.each do |hvac_system|
1296
+ if hvac_system.is_a? HPXML::HeatingSystem
1297
+ next if hvac_system.is_heat_pump_backup_system
1298
+
1299
+ htg_cap += hvac_system.heating_capacity.to_f
1300
+ elsif hvac_system.is_a? HPXML::CoolingSystem
1301
+ clg_cap += hvac_system.cooling_capacity.to_f
1302
+ if hvac_system.has_integrated_heating
1303
+ htg_cap += hvac_system.integrated_heating_system_capacity.to_f
1304
+ end
1305
+ elsif hvac_system.is_a? HPXML::HeatPump
1306
+ htg_cap += hvac_system.heating_capacity.to_f
1307
+ clg_cap += hvac_system.cooling_capacity.to_f
1308
+ if hvac_system.backup_type == HPXML::HeatPumpBackupTypeIntegrated
1309
+ hp_backup_cap += hvac_system.backup_heating_capacity.to_f
1310
+ elsif hvac_system.backup_type == HPXML::HeatPumpBackupTypeSeparate
1311
+ hp_backup_cap += hvac_system.backup_system.heating_capacity.to_f
1158
1312
  end
1159
1313
  end
1160
1314
  end
1161
- end
1315
+ results_out << [line_break]
1316
+ results_out << ['HVAC Capacity: Heating (Btu/h)', htg_cap.round(1)]
1317
+ results_out << ['HVAC Capacity: Cooling (Btu/h)', clg_cap.round(1)]
1318
+ results_out << ['HVAC Capacity: Heat Pump Backup (Btu/h)', hp_backup_cap.round(1)]
1319
+
1320
+ # HVAC design temperatures
1321
+ results_out << [line_break]
1322
+ results_out << ['HVAC Design Temperature: Heating (F)', @hpxml.hvac_plant.temp_heating.round(2)]
1323
+ results_out << ['HVAC Design Temperature: Cooling (F)', @hpxml.hvac_plant.temp_cooling.round(2)]
1324
+
1325
+ # HVAC design loads
1326
+ results_out << [line_break]
1327
+ results_out << ['HVAC Design Load: Heating: Total (Btu/h)', @hpxml.hvac_plant.hdl_total.round(1)]
1328
+ results_out << ['HVAC Design Load: Heating: Ducts (Btu/h)', @hpxml.hvac_plant.hdl_ducts.round(1)]
1329
+ results_out << ['HVAC Design Load: Heating: Windows (Btu/h)', @hpxml.hvac_plant.hdl_windows.round(1)]
1330
+ results_out << ['HVAC Design Load: Heating: Skylights (Btu/h)', @hpxml.hvac_plant.hdl_skylights.round(1)]
1331
+ results_out << ['HVAC Design Load: Heating: Doors (Btu/h)', @hpxml.hvac_plant.hdl_doors.round(1)]
1332
+ results_out << ['HVAC Design Load: Heating: Walls (Btu/h)', @hpxml.hvac_plant.hdl_walls.round(1)]
1333
+ results_out << ['HVAC Design Load: Heating: Roofs (Btu/h)', @hpxml.hvac_plant.hdl_roofs.round(1)]
1334
+ results_out << ['HVAC Design Load: Heating: Floors (Btu/h)', @hpxml.hvac_plant.hdl_floors.round(1)]
1335
+ results_out << ['HVAC Design Load: Heating: Slabs (Btu/h)', @hpxml.hvac_plant.hdl_slabs.round(1)]
1336
+ results_out << ['HVAC Design Load: Heating: Ceilings (Btu/h)', @hpxml.hvac_plant.hdl_ceilings.round(1)]
1337
+ results_out << ['HVAC Design Load: Heating: Infiltration/Ventilation (Btu/h)', @hpxml.hvac_plant.hdl_infilvent.round(1)]
1338
+ results_out << ['HVAC Design Load: Cooling Sensible: Total (Btu/h)', @hpxml.hvac_plant.cdl_sens_total.round(1)]
1339
+ results_out << ['HVAC Design Load: Cooling Sensible: Ducts (Btu/h)', @hpxml.hvac_plant.cdl_sens_ducts.round(1)]
1340
+ results_out << ['HVAC Design Load: Cooling Sensible: Windows (Btu/h)', @hpxml.hvac_plant.cdl_sens_windows.round(1)]
1341
+ results_out << ['HVAC Design Load: Cooling Sensible: Skylights (Btu/h)', @hpxml.hvac_plant.cdl_sens_skylights.round(1)]
1342
+ results_out << ['HVAC Design Load: Cooling Sensible: Doors (Btu/h)', @hpxml.hvac_plant.cdl_sens_doors.round(1)]
1343
+ results_out << ['HVAC Design Load: Cooling Sensible: Walls (Btu/h)', @hpxml.hvac_plant.cdl_sens_walls.round(1)]
1344
+ results_out << ['HVAC Design Load: Cooling Sensible: Roofs (Btu/h)', @hpxml.hvac_plant.cdl_sens_roofs.round(1)]
1345
+ results_out << ['HVAC Design Load: Cooling Sensible: Floors (Btu/h)', @hpxml.hvac_plant.cdl_sens_floors.round(1)]
1346
+ results_out << ['HVAC Design Load: Cooling Sensible: Slabs (Btu/h)', @hpxml.hvac_plant.cdl_sens_slabs.round(1)]
1347
+ results_out << ['HVAC Design Load: Cooling Sensible: Ceilings (Btu/h)', @hpxml.hvac_plant.cdl_sens_ceilings.round(1)]
1348
+ results_out << ['HVAC Design Load: Cooling Sensible: Infiltration/Ventilation (Btu/h)', @hpxml.hvac_plant.cdl_sens_infilvent.round(1)]
1349
+ results_out << ['HVAC Design Load: Cooling Sensible: Internal Gains (Btu/h)', @hpxml.hvac_plant.cdl_sens_intgains.round(1)]
1350
+ results_out << ['HVAC Design Load: Cooling Latent: Total (Btu/h)', @hpxml.hvac_plant.cdl_lat_total.round(1)]
1351
+ results_out << ['HVAC Design Load: Cooling Latent: Ducts (Btu/h)', @hpxml.hvac_plant.cdl_lat_ducts.round(1)]
1352
+ results_out << ['HVAC Design Load: Cooling Latent: Infiltration/Ventilation (Btu/h)', @hpxml.hvac_plant.cdl_lat_infilvent.round(1)]
1353
+ results_out << ['HVAC Design Load: Cooling Latent: Internal Gains (Btu/h)', @hpxml.hvac_plant.cdl_lat_intgains.round(1)]
1162
1354
 
1163
- def get_runner_output_name(obj)
1164
- return "#{obj.name} #{obj.annual_units}"
1355
+ return results_out
1165
1356
  end
1166
1357
 
1167
- def append_eri_results(outputs, results_out, line_break)
1358
+ def append_eri_results(results_out, line_break)
1168
1359
  def ordered_values(hash, sys_ids)
1169
1360
  vals = []
1170
1361
  sys_ids.each do |sys_id|
@@ -1184,7 +1375,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1184
1375
  end
1185
1376
 
1186
1377
  def get_eec_value_numerator(unit)
1187
- if ['HSPF', 'SEER', 'EER', 'CEER'].include? unit
1378
+ if ['HSPF', 'HSPF2', 'SEER', 'SEER2', 'EER', 'CEER'].include? unit
1188
1379
  return 3.413
1189
1380
  elsif ['AFUE', 'COP', 'Percent', 'EF'].include? unit
1190
1381
  return 1.0
@@ -1216,6 +1407,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1216
1407
  end
1217
1408
  end
1218
1409
  @hpxml.cooling_systems.each do |clg_system|
1410
+ if clg_system.has_integrated_heating && clg_system.integrated_heating_system_fraction_heat_load_served > 0
1411
+ # Cooling system w/ integrated heating (e.g., Room AC w/ electric resistance heating)
1412
+ htg_ids << clg_system.id
1413
+ htg_seed_id_map[clg_system.id] = clg_system.htg_seed_id
1414
+ htg_fuels[clg_system.id] = clg_system.integrated_heating_system_fuel
1415
+ htg_eecs[clg_system.id] = get_eec_value_numerator('Percent') / clg_system.integrated_heating_system_efficiency_percent
1416
+ end
1417
+
1219
1418
  next unless clg_system.fraction_cool_load_served > 0
1220
1419
 
1221
1420
  clg_ids << clg_system.id
@@ -1223,6 +1422,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1223
1422
  clg_fuels[clg_system.id] = clg_system.cooling_system_fuel
1224
1423
  if not clg_system.cooling_efficiency_seer.nil?
1225
1424
  clg_eecs[clg_system.id] = get_eec_value_numerator('SEER') / clg_system.cooling_efficiency_seer
1425
+ elsif not clg_system.cooling_efficiency_seer2.nil?
1426
+ clg_eecs[clg_system.id] = get_eec_value_numerator('SEER2') / clg_system.cooling_efficiency_seer2
1226
1427
  elsif not clg_system.cooling_efficiency_eer.nil?
1227
1428
  clg_eecs[clg_system.id] = get_eec_value_numerator('EER') / clg_system.cooling_efficiency_eer
1228
1429
  elsif not clg_system.cooling_efficiency_ceer.nil?
@@ -1239,6 +1440,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1239
1440
  htg_fuels[heat_pump.id] = heat_pump.heat_pump_fuel
1240
1441
  if not heat_pump.heating_efficiency_hspf.nil?
1241
1442
  htg_eecs[heat_pump.id] = get_eec_value_numerator('HSPF') / heat_pump.heating_efficiency_hspf
1443
+ elsif not heat_pump.heating_efficiency_hspf2.nil?
1444
+ htg_eecs[heat_pump.id] = get_eec_value_numerator('HSPF2') / heat_pump.heating_efficiency_hspf2
1242
1445
  elsif not heat_pump.heating_efficiency_cop.nil?
1243
1446
  htg_eecs[heat_pump.id] = get_eec_value_numerator('COP') / heat_pump.heating_efficiency_cop
1244
1447
  end
@@ -1247,8 +1450,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1247
1450
 
1248
1451
  clg_ids << heat_pump.id
1249
1452
  clg_seed_id_map[heat_pump.id] = heat_pump.clg_seed_id
1453
+ clg_fuels[heat_pump.id] = heat_pump.heat_pump_fuel
1250
1454
  if not heat_pump.cooling_efficiency_seer.nil?
1251
1455
  clg_eecs[heat_pump.id] = get_eec_value_numerator('SEER') / heat_pump.cooling_efficiency_seer
1456
+ elsif not heat_pump.cooling_efficiency_seer2.nil?
1457
+ clg_eecs[heat_pump.id] = get_eec_value_numerator('SEER2') / heat_pump.cooling_efficiency_seer2
1252
1458
  elsif not heat_pump.cooling_efficiency_eer.nil?
1253
1459
  clg_eecs[heat_pump.id] = get_eec_value_numerator('EER') / heat_pump.cooling_efficiency_eer
1254
1460
  end
@@ -1280,6 +1486,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1280
1486
  end
1281
1487
  @hpxml.ventilation_fans.each do |vent_fan|
1282
1488
  next unless vent_fan.used_for_whole_building_ventilation
1489
+ next if vent_fan.is_cfis_supplemental_fan?
1283
1490
 
1284
1491
  if not vent_fan.preheating_fuel.nil?
1285
1492
  prehtg_ids << vent_fan.id
@@ -1300,9 +1507,14 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1300
1507
  @loads[LT::Heating].annual_output_by_system[htg_system.id] = htg_system.fraction_heat_load_served * @loads[LT::Heating].annual_output
1301
1508
  end
1302
1509
  (@hpxml.cooling_systems + @hpxml.heat_pumps).each do |clg_system|
1303
- next unless clg_ids.include? clg_system.id
1510
+ if clg_ids.include? clg_system.id
1511
+ @loads[LT::Cooling].annual_output_by_system[clg_system.id] = clg_system.fraction_cool_load_served * @loads[LT::Cooling].annual_output
1512
+ end
1513
+ 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)
1304
1514
 
1305
- @loads[LT::Cooling].annual_output_by_system[clg_system.id] = clg_system.fraction_cool_load_served * @loads[LT::Cooling].annual_output
1515
+ if htg_ids.include? clg_system.id
1516
+ @loads[LT::Heating].annual_output_by_system[clg_system.id] = clg_system.integrated_heating_system_fraction_heat_load_served * @loads[LT::Heating].annual_output
1517
+ end
1306
1518
  end
1307
1519
 
1308
1520
  # Handle dual-fuel heat pumps
@@ -1350,7 +1562,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1350
1562
  end
1351
1563
  end
1352
1564
 
1353
- # Collect energy consumptions (EC) by system
1565
+ # Collect energy consumption (EC) by system
1354
1566
  htg_ecs, clg_ecs, dhw_ecs, prehtg_ecs, preclg_ecs = {}, {}, {}, {}, {}
1355
1567
  eut_map = { EUT::Heating => htg_ecs,
1356
1568
  EUT::HeatingHeatPumpBackup => htg_ecs,
@@ -1363,7 +1575,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1363
1575
  EUT::MechVentPreheat => prehtg_ecs,
1364
1576
  EUT::MechVentPrecool => preclg_ecs }
1365
1577
  @end_uses.each do |key, end_use|
1366
- fuel_type, end_use_type = key
1578
+ _fuel_type, end_use_type = key
1367
1579
  ec_obj = eut_map[end_use_type]
1368
1580
  next if ec_obj.nil?
1369
1581
 
@@ -1417,23 +1629,33 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1417
1629
  return results_out
1418
1630
  end
1419
1631
 
1420
- def write_timeseries_output_results(runner, outputs, output_format,
1421
- timeseries_output_path,
1422
- timeseries_frequency,
1423
- include_timeseries_total_consumptions,
1424
- include_timeseries_fuel_consumptions,
1425
- include_timeseries_end_use_consumptions,
1426
- include_timeseries_emissions,
1427
- include_timeseries_hot_water_uses,
1428
- include_timeseries_total_loads,
1429
- include_timeseries_component_loads,
1430
- include_timeseries_zone_temperatures,
1431
- include_timeseries_airflows,
1432
- include_timeseries_weather,
1433
- timestamps_dst,
1434
- timestamps_utc)
1632
+ def report_timeseries_output_results(runner, outputs, output_format,
1633
+ timeseries_output_path,
1634
+ timeseries_frequency,
1635
+ include_timeseries_total_consumptions,
1636
+ include_timeseries_fuel_consumptions,
1637
+ include_timeseries_end_use_consumptions,
1638
+ include_timeseries_emissions,
1639
+ include_timeseries_emission_fuels,
1640
+ include_timeseries_emission_end_uses,
1641
+ include_timeseries_hot_water_uses,
1642
+ include_timeseries_total_loads,
1643
+ include_timeseries_component_loads,
1644
+ include_timeseries_unmet_hours,
1645
+ include_timeseries_zone_temperatures,
1646
+ include_timeseries_airflows,
1647
+ include_timeseries_weather,
1648
+ add_dst_column,
1649
+ add_utc_column,
1650
+ timestamps_dst,
1651
+ timestamps_utc,
1652
+ use_dview_format)
1435
1653
  return if @timestamps.nil?
1436
1654
 
1655
+ if not ['timestep', 'hourly', 'daily', 'monthly'].include? timeseries_frequency
1656
+ fail "Unexpected timeseries_frequency: #{timeseries_frequency}."
1657
+ end
1658
+
1437
1659
  # Set rounding precision for timeseries (e.g., hourly) outputs.
1438
1660
  # Note: Make sure to round outputs with sufficient resolution for the worst case -- i.e., 1 minute date instead of hourly data.
1439
1661
  n_digits = 2 # Default for hourly (or longer) data
@@ -1445,30 +1667,15 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1445
1667
  end
1446
1668
  end
1447
1669
 
1448
- # Time column(s)
1449
- if ['timestep', 'hourly', 'daily', 'monthly'].include? timeseries_frequency
1450
- data = ['Time', nil]
1451
- else
1452
- fail "Unexpected timeseries_frequency: #{timeseries_frequency}."
1453
- end
1454
- @timestamps.each do |timestamp|
1455
- data << timestamp
1456
- end
1457
-
1458
- if timestamps_dst
1459
- timestamps2 = [['TimeDST', nil]]
1460
- timestamps_dst.each do |timestamp|
1461
- timestamps2[0] << timestamp
1462
- end
1670
+ # Initial output data w/ Time column(s)
1671
+ data = ['Time', nil] + @timestamps
1672
+ if add_dst_column
1673
+ timestamps2 = [['TimeDST', nil] + timestamps_dst]
1463
1674
  else
1464
1675
  timestamps2 = []
1465
1676
  end
1466
-
1467
- if timestamps_utc
1468
- timestamps3 = [['TimeUTC', nil]]
1469
- timestamps_utc.each do |timestamp|
1470
- timestamps3[0] << timestamp
1471
- end
1677
+ if add_utc_column
1678
+ timestamps3 = [['TimeUTC', nil] + timestamps_utc]
1472
1679
  else
1473
1680
  timestamps3 = []
1474
1681
  end
@@ -1499,18 +1706,39 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1499
1706
  end_use_data = []
1500
1707
  end
1501
1708
  if include_timeseries_emissions
1502
- # Include total and disaggregated by fuel
1503
1709
  emissions_data = []
1504
1710
  @emissions.values.each do |emission|
1505
- emissions_data << [emission.name, emission.timeseries_units] + emission.timeseries_output.map { |v| v.round(5) }
1711
+ next if emission.timeseries_output.sum(0.0) == 0
1712
+
1713
+ emissions_data << ["#{emission.name}: Total", emission.timeseries_units] + emission.timeseries_output.map { |v| v.round(5) }
1714
+ end
1715
+ else
1716
+ emissions_data = []
1717
+ end
1718
+ if include_timeseries_emission_fuels
1719
+ emission_fuel_data = []
1720
+ @emissions.values.each do |emission|
1506
1721
  emission.timeseries_output_by_fuel.each do |fuel, timeseries_output|
1507
1722
  next if timeseries_output.sum(0.0) == 0
1508
1723
 
1509
- emissions_data << [emission.name.gsub(': Total', ': ' + fuel), emission.timeseries_units] + timeseries_output.map { |v| v.round(5) }
1724
+ emission_fuel_data << ["#{emission.name}: #{fuel}: Total", emission.timeseries_units] + timeseries_output.map { |v| v.round(5) }
1510
1725
  end
1511
1726
  end
1512
1727
  else
1513
- emissions_data = []
1728
+ emission_fuel_data = []
1729
+ end
1730
+ if include_timeseries_emission_end_uses
1731
+ emission_end_use_data = []
1732
+ @emissions.values.each do |emission|
1733
+ emission.timeseries_output_by_end_use.each do |key, timeseries_output|
1734
+ next if timeseries_output.sum(0.0) == 0
1735
+
1736
+ fuel_type, end_use_type = key
1737
+ emission_end_use_data << ["#{emission.name}: #{fuel_type}: #{end_use_type}", emission.timeseries_units] + timeseries_output.map { |v| v.round(5) }
1738
+ end
1739
+ end
1740
+ else
1741
+ emission_end_use_data = []
1514
1742
  end
1515
1743
  if include_timeseries_hot_water_uses
1516
1744
  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) } }
@@ -1527,6 +1755,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1527
1755
  else
1528
1756
  comp_loads_data = []
1529
1757
  end
1758
+ if include_timeseries_unmet_hours
1759
+ unmet_hours_data = @unmet_hours.values.map { |x| [x.name, x.timeseries_units] + x.timeseries_output.map { |v| v.round(n_digits) } }
1760
+ else
1761
+ unmet_hours_data = []
1762
+ end
1530
1763
  if include_timeseries_zone_temperatures
1531
1764
  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) } }
1532
1765
  else
@@ -1550,17 +1783,17 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1550
1783
  output_variables_data = []
1551
1784
  end
1552
1785
 
1553
- return if (total_energy_data.size + fuel_data.size + end_use_data.size + emissions_data.size +
1554
- hot_water_use_data.size + total_loads_data.size + comp_loads_data.size +
1786
+ return if (total_energy_data.size + fuel_data.size + end_use_data.size + emissions_data.size + emission_fuel_data.size +
1787
+ emission_end_use_data.size + hot_water_use_data.size + total_loads_data.size + comp_loads_data.size + unmet_hours_data.size +
1555
1788
  zone_temps_data.size + airflows_data.size + weather_data.size + output_variables_data.size) == 0
1556
1789
 
1557
1790
  fail 'Unable to obtain timestamps.' if @timestamps.empty?
1558
1791
 
1559
1792
  if ['csv'].include? output_format
1560
1793
  # Assemble data
1561
- data = data.zip(*timestamps2, *timestamps3, *total_energy_data, *fuel_data, *end_use_data,
1562
- *emissions_data, *hot_water_use_data, *total_loads_data, *comp_loads_data,
1563
- *zone_temps_data, *airflows_data, *weather_data, *output_variables_data)
1794
+ data = data.zip(*timestamps2, *timestamps3, *total_energy_data, *fuel_data, *end_use_data, *emissions_data,
1795
+ *emission_fuel_data, *emission_end_use_data, *hot_water_use_data, *total_loads_data, *comp_loads_data,
1796
+ *unmet_hours_data, *zone_temps_data, *airflows_data, *weather_data, *output_variables_data)
1564
1797
 
1565
1798
  # Error-check
1566
1799
  n_elements = []
@@ -1571,6 +1804,46 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1571
1804
  fail "Inconsistent number of array elements: #{n_elements.uniq}."
1572
1805
  end
1573
1806
 
1807
+ if use_dview_format
1808
+ # Remove Time column(s)
1809
+ while data[0][0].include? 'Time'
1810
+ data = data.map { |a| a[1..-1] }
1811
+ end
1812
+
1813
+ # Add header per DataFileTemplate.pdf; see https://github.com/NREL/wex/wiki/DView
1814
+ year = @hpxml.header.sim_calendar_year
1815
+ start_day = Schedule.get_day_num_from_month_day(year, @hpxml.header.sim_begin_month, @hpxml.header.sim_begin_day)
1816
+ start_hr = (start_day - 1) * 24
1817
+ if timeseries_frequency == 'timestep'
1818
+ interval_hrs = @hpxml.header.timestep / 60.0
1819
+ elsif timeseries_frequency == 'hourly'
1820
+ interval_hrs = 1.0
1821
+ elsif timeseries_frequency == 'daily'
1822
+ interval_hrs = 24.0
1823
+ elsif timeseries_frequency == 'monthly'
1824
+ interval_hrs = Constants.NumDaysInYear(year) * 24.0 / 12
1825
+ end
1826
+ header_data = [['wxDVFileHeaderVer.1'],
1827
+ data[0].map { |d| d.sub(':', '|') }, # Series name (series can be organized into groups by entering Group Name|Series Name)
1828
+ data[0].map { |_d| start_hr + interval_hrs / 2.0 }, # Start time of the first data point; 0.5 implies average over the first hour
1829
+ data[0].map { |_d| interval_hrs }, # Time interval in hours
1830
+ data[1]] # Units
1831
+ data.delete_at(1) # Remove units, added to header data above
1832
+ data.delete_at(0) # Remove series name, added to header data above
1833
+
1834
+ # Apply daylight savings
1835
+ if timeseries_frequency == 'timestep' || timeseries_frequency == 'hourly'
1836
+ if @hpxml.header.dst_enabled
1837
+ dst_start_ix, dst_end_ix = OutputMethods.get_dst_start_end_indexes(@timestamps, timestamps_dst)
1838
+ dst_end_ix.downto(dst_start_ix + 1) do |i|
1839
+ data[i + 1] = data[i]
1840
+ end
1841
+ end
1842
+ end
1843
+
1844
+ data.insert(0, *header_data) # Add header data to beginning
1845
+ end
1846
+
1574
1847
  # Write file
1575
1848
  CSV.open(timeseries_output_path, 'wb') { |csv| data.to_a.each { |elem| csv << elem } }
1576
1849
  elsif ['json', 'msgpack'].include? output_format
@@ -1580,8 +1853,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1580
1853
  h['TimeDST'] = timestamps2[2..-1] if timestamps_dst
1581
1854
  h['TimeUTC'] = timestamps3[2..-1] if timestamps_utc
1582
1855
 
1583
- [total_energy_data, fuel_data, end_use_data, emissions_data,
1584
- hot_water_use_data, total_loads_data, comp_loads_data,
1856
+ [total_energy_data, fuel_data, end_use_data, emissions_data, emission_fuel_data,
1857
+ emission_end_use_data, hot_water_use_data, total_loads_data, comp_loads_data, unmet_hours_data,
1585
1858
  zone_temps_data, airflows_data, weather_data, output_variables_data].each do |d|
1586
1859
  d.each do |o|
1587
1860
  grp, name = o[0].split(':', 2)
@@ -1635,7 +1908,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1635
1908
  rows = @msgpackData['MeterData'][msgpack_timeseries_name]['Rows']
1636
1909
  indexes = cols.each_index.select { |i| meter_names.include? cols[i]['Variable'] }
1637
1910
  vals = []
1638
- rows.each_with_index do |row, idx|
1911
+ rows.each_with_index do |row, _idx|
1639
1912
  row = row[row.keys[0]]
1640
1913
  val = 0.0
1641
1914
  indexes.each do |i|
@@ -1646,7 +1919,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1646
1919
  return vals
1647
1920
  end
1648
1921
 
1649
- def get_report_variable_data_timeseries(key_values, variables, unit_conv, unit_adder, timeseries_frequency, is_negative: false, ems_shift: false, hourly: false)
1922
+ def get_report_variable_data_timeseries(key_values, variables, unit_conv, unit_adder, timeseries_frequency, is_negative: false, ems_shift: false)
1650
1923
  return [0.0] * @timestamps.size if variables.empty?
1651
1924
 
1652
1925
  if key_values.uniq.size > 1 && key_values.include?('EMS') && ems_shift
@@ -1668,7 +1941,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1668
1941
  rows = msgpack_data['Rows']
1669
1942
  indexes = cols.each_index.select { |i| keys_vars.include? cols[i]['Variable'] }
1670
1943
  vals = []
1671
- rows.each_with_index do |row, idx|
1944
+ rows.each_with_index do |row, _idx|
1672
1945
  row = row[row.keys[0]]
1673
1946
  val = 0.0
1674
1947
  indexes.each do |i|
@@ -1690,7 +1963,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1690
1963
  return vals
1691
1964
  end
1692
1965
 
1693
- def get_report_variable_data_timeseries_key_values_and_units(timeseries_frequency, var)
1966
+ def get_report_variable_data_timeseries_key_values_and_units(var)
1694
1967
  keys = []
1695
1968
  units = ''
1696
1969
  if not @msgpackDataTimeseries.nil?
@@ -1729,21 +2002,23 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1729
2002
  # Annual
1730
2003
  orig_value = obj.annual_output_by_system[sys_id]
1731
2004
  obj.annual_output_by_system[sys_id] = orig_value * mult
1732
- sync_obj.annual_output += (orig_value * mult - orig_value)
2005
+ if not sync_obj.nil?
2006
+ sync_obj.annual_output += (orig_value * mult - orig_value)
2007
+ end
1733
2008
 
1734
2009
  # Timeseries
1735
2010
  if not obj.timeseries_output_by_system.empty?
1736
2011
  orig_values = obj.timeseries_output_by_system[sys_id]
1737
2012
  obj.timeseries_output_by_system[sys_id] = obj.timeseries_output_by_system[sys_id].map { |x| x * mult }
1738
2013
  diffs = obj.timeseries_output_by_system[sys_id].zip(orig_values).map { |x, y| x - y }
1739
- sync_obj.timeseries_output = sync_obj.timeseries_output.zip(diffs).map { |x, y| x + y }
2014
+ if not sync_obj.nil?
2015
+ sync_obj.timeseries_output = sync_obj.timeseries_output.zip(diffs).map { |x, y| x + y }
2016
+ end
1740
2017
  end
1741
2018
 
1742
2019
  # Hourly Electricity (for Cambium)
1743
2020
  if obj.is_a?(EndUse) && (not obj.hourly_output_by_system.empty?)
1744
- orig_values = obj.hourly_output_by_system[sys_id]
1745
2021
  obj.hourly_output_by_system[sys_id] = obj.hourly_output_by_system[sys_id].map { |x| x * mult }
1746
- diffs = obj.hourly_output_by_system[sys_id].zip(orig_values).map { |x, y| x - y }
1747
2022
  end
1748
2023
  end
1749
2024
 
@@ -1814,27 +2089,30 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1814
2089
  end
1815
2090
 
1816
2091
  class EndUse < BaseOutput
1817
- def initialize(variables: [], is_negative: false)
2092
+ def initialize(variables: [], is_negative: false, is_storage: false)
1818
2093
  super()
1819
2094
  @variables = variables
1820
2095
  @is_negative = is_negative
2096
+ @is_storage = is_storage
1821
2097
  @timeseries_output_by_system = {}
1822
2098
  @annual_output_by_system = {}
1823
2099
  # These outputs used to apply Cambium hourly electricity factors
1824
2100
  @hourly_output = []
1825
2101
  @hourly_output_by_system = {}
1826
2102
  end
1827
- attr_accessor(:variables, :is_negative, :annual_output_by_system, :timeseries_output_by_system,
2103
+ attr_accessor(:variables, :is_negative, :is_storage, :annual_output_by_system, :timeseries_output_by_system,
1828
2104
  :hourly_output, :hourly_output_by_system)
1829
2105
  end
1830
2106
 
1831
2107
  class Emission < BaseOutput
1832
2108
  def initialize()
1833
2109
  super()
2110
+ @timeseries_output_by_end_use = {}
1834
2111
  @timeseries_output_by_fuel = {}
1835
2112
  @annual_output_by_fuel = {}
2113
+ @annual_output_by_end_use = {}
1836
2114
  end
1837
- attr_accessor(:annual_output_by_fuel, :timeseries_output_by_fuel)
2115
+ attr_accessor(:annual_output_by_fuel, :annual_output_by_end_use, :timeseries_output_by_fuel, :timeseries_output_by_end_use)
1838
2116
  end
1839
2117
 
1840
2118
  class HotWater < BaseOutput
@@ -1877,11 +2155,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1877
2155
  end
1878
2156
 
1879
2157
  class UnmetHours < BaseOutput
1880
- def initialize(col_name:)
2158
+ def initialize(ems_variable:)
1881
2159
  super()
1882
- @col_name = col_name
2160
+ @ems_variable = ems_variable
1883
2161
  end
1884
- attr_accessor(:col_name)
2162
+ attr_accessor(:ems_variable)
1885
2163
  end
1886
2164
 
1887
2165
  class IdealLoad < BaseOutput
@@ -1934,7 +2212,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1934
2212
  attr_accessor()
1935
2213
  end
1936
2214
 
1937
- def setup_outputs(user_output_variables = nil)
2215
+ def setup_outputs(called_from_outputs_method, user_output_variables = nil)
1938
2216
  def get_timeseries_units_from_fuel_type(fuel_type)
1939
2217
  if fuel_type == FT::Elec
1940
2218
  return 'kWh'
@@ -1986,6 +2264,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
1986
2264
  is_negative: true)
1987
2265
  @end_uses[[FT::Elec, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Generator]),
1988
2266
  is_negative: true)
2267
+ @end_uses[[FT::Elec, EUT::Battery]] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, EUT::Battery]),
2268
+ is_storage: true)
1989
2269
  @end_uses[[FT::Gas, EUT::Heating]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::Heating]))
1990
2270
  @end_uses[[FT::Gas, EUT::HeatingHeatPumpBackup]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::HeatingHeatPumpBackup]))
1991
2271
  @end_uses[[FT::Gas, EUT::HotWater]] = EndUse.new(variables: get_object_variables(EUT, [FT::Gas, EUT::HotWater]))
@@ -2048,6 +2328,11 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2048
2328
  @end_uses[[FT::Coal, EUT::Lighting]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::Lighting]))
2049
2329
  @end_uses[[FT::Coal, EUT::Fireplace]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::Fireplace]))
2050
2330
  @end_uses[[FT::Coal, EUT::Generator]] = EndUse.new(variables: get_object_variables(EUT, [FT::Coal, EUT::Generator]))
2331
+ if not called_from_outputs_method
2332
+ # Temporary end use to disaggregate 8760 GSHP shared loop pump energy into heating vs cooling.
2333
+ # This end use will not appear in output data/files.
2334
+ @end_uses[[FT::Elec, 'TempGSHPSharedPump']] = EndUse.new(variables: get_object_variables(EUT, [FT::Elec, 'TempGSHPSharedPump']))
2335
+ end
2051
2336
  @end_uses.each do |key, end_use|
2052
2337
  fuel_type, end_use_type = key
2053
2338
  end_use.name = "End Use: #{fuel_type}: #{end_use_type}"
@@ -2086,14 +2371,16 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2086
2371
 
2087
2372
  # Emissions
2088
2373
  @emissions = {}
2089
- emissions_scenario_names = eval(@model.getBuilding.additionalProperties.getFeatureAsString('emissions_scenario_names').get)
2090
- emissions_scenario_types = eval(@model.getBuilding.additionalProperties.getFeatureAsString('emissions_scenario_types').get)
2091
- emissions_scenario_names.each_with_index do |scenario_name, i|
2092
- scenario_type = emissions_scenario_types[i]
2093
- @emissions[[scenario_type, scenario_name]] = Emission.new()
2094
- @emissions[[scenario_type, scenario_name]].name = "Emissions: #{scenario_type}: #{scenario_name}: Total"
2095
- @emissions[[scenario_type, scenario_name]].annual_units = 'lb'
2096
- @emissions[[scenario_type, scenario_name]].timeseries_units = 'lb'
2374
+ if not @model.nil?
2375
+ emissions_scenario_names = eval(@model.getBuilding.additionalProperties.getFeatureAsString('emissions_scenario_names').get)
2376
+ emissions_scenario_types = eval(@model.getBuilding.additionalProperties.getFeatureAsString('emissions_scenario_types').get)
2377
+ emissions_scenario_names.each_with_index do |scenario_name, i|
2378
+ scenario_type = emissions_scenario_types[i]
2379
+ @emissions[[scenario_type, scenario_name]] = Emission.new()
2380
+ @emissions[[scenario_type, scenario_name]].name = "Emissions: #{scenario_type}: #{scenario_name}"
2381
+ @emissions[[scenario_type, scenario_name]].annual_units = 'lb'
2382
+ @emissions[[scenario_type, scenario_name]].timeseries_units = 'lb'
2383
+ end
2097
2384
  end
2098
2385
 
2099
2386
  # Hot Water Uses
@@ -2186,12 +2473,13 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2186
2473
 
2187
2474
  # Unmet Hours
2188
2475
  @unmet_hours = {}
2189
- @unmet_hours[UHT::Heating] = UnmetHours.new(col_name: 'During Heating')
2190
- @unmet_hours[UHT::Cooling] = UnmetHours.new(col_name: 'During Cooling')
2476
+ @unmet_hours[UHT::Heating] = UnmetHours.new(ems_variable: 'htg_unmet_hours')
2477
+ @unmet_hours[UHT::Cooling] = UnmetHours.new(ems_variable: 'clg_unmet_hours')
2191
2478
 
2192
2479
  @unmet_hours.each do |load_type, unmet_hour|
2193
2480
  unmet_hour.name = "Unmet Hours: #{load_type}"
2194
2481
  unmet_hour.annual_units = 'hr'
2482
+ unmet_hour.timeseries_units = 'hr'
2195
2483
  end
2196
2484
 
2197
2485
  # Ideal System Loads (expected load that is not met by the HVAC systems)
@@ -2211,7 +2499,7 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2211
2499
 
2212
2500
  @peak_loads.each do |load_type, peak_load|
2213
2501
  peak_load.name = "Peak Load: #{load_type}"
2214
- peak_load.annual_units = 'kBtu'
2502
+ peak_load.annual_units = 'kBtu/hr'
2215
2503
  end
2216
2504
 
2217
2505
  # Zone Temperatures
@@ -2403,15 +2691,23 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2403
2691
  return { [FT::Elec, end_use] => ["Lights #{EPlus::FuelTypeElectricity} Energy"] }
2404
2692
 
2405
2693
  elsif object.to_ElectricLoadCenterInverterPVWatts.is_initialized
2406
- return { [FT::Elec, EUT::PV] => ["Inverter AC Output #{EPlus::FuelTypeElectricity} Energy"] }
2694
+ return { [FT::Elec, EUT::PV] => ['Inverter Conversion Loss Decrement Energy'] }
2695
+
2696
+ elsif object.to_GeneratorPVWatts.is_initialized
2697
+ return { [FT::Elec, EUT::PV] => ["Generator Produced DC #{EPlus::FuelTypeElectricity} Energy"] }
2407
2698
 
2408
2699
  elsif object.to_GeneratorMicroTurbine.is_initialized
2409
2700
  fuel = object.to_GeneratorMicroTurbine.get.fuelType
2410
2701
  return { [FT::Elec, EUT::Generator] => ["Generator Produced AC #{EPlus::FuelTypeElectricity} Energy"],
2411
2702
  [to_ft[fuel], EUT::Generator] => ["Generator #{fuel} HHV Basis Energy"] }
2412
2703
 
2704
+ elsif object.to_ElectricLoadCenterStorageLiIonNMCBattery.is_initialized
2705
+ # return { [FT::Elec, EUT::Battery] => ['Electric Storage Production Decrement Energy', 'Electric Storage Discharge Energy', 'Electric Storage Thermal Loss Energy'] }
2706
+ return { [FT::Elec, EUT::Battery] => ['Electric Storage Production Decrement Energy', 'Electric Storage Discharge Energy'] }
2707
+
2413
2708
  elsif object.to_ElectricEquipment.is_initialized
2414
2709
  end_use = { Constants.ObjectNameHotWaterRecircPump => EUT::HotWaterRecircPump,
2710
+ Constants.ObjectNameGSHPSharedPump => 'TempGSHPSharedPump',
2415
2711
  Constants.ObjectNameClothesWasher => EUT::ClothesWasher,
2416
2712
  Constants.ObjectNameClothesDryer => EUT::ClothesDryer,
2417
2713
  Constants.ObjectNameDishwasher => EUT::Dishwasher,
@@ -2461,6 +2757,8 @@ class ReportSimulationOutput < OpenStudio::Measure::ReportingMeasure
2461
2757
  elsif object.name.to_s.include? Constants.ObjectNameWaterHeaterAdjustment(nil)
2462
2758
  fuel = object.additionalProperties.getFeatureAsString('FuelType').get
2463
2759
  return { [to_ft[fuel], EUT::HotWater] => [object.name.to_s] }
2760
+ elsif object.name.to_s.include? Constants.ObjectNameBatteryLossesAdjustment(nil)
2761
+ return { [FT::Elec, EUT::Battery] => [object.name.to_s] }
2464
2762
  else
2465
2763
  return { ems: [object.name.to_s] }
2466
2764
  end