urbanopt-cli 0.8.2 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (650) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -6
  3. data/CHANGELOG.md +21 -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 +601 -101
  635. data/scripts/setup-env.bat +6 -7
  636. data/uo_cli.gemspec +6 -5
  637. metadata +121 -36
  638. data/example_files/residential/exhaust.tsv +0 -3
  639. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/hvac_equipment_efficiency.csv +0 -493
  640. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/water_heater_efficiency.csv +0 -157
  641. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/HPXMLvalidator.xml +0 -620
  642. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/validator.rb +0 -107
  643. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.rb +0 -450
  644. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.xml +0 -85
  645. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/resources/constants.rb +0 -72
  646. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/tests/hpxml_output_report_test.rb +0 -290
  647. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_10kW.csv +0 -8761
  648. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_1kW.csv +0 -8761
  649. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_None.csv +0 -8761
  650. 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