urbanopt-cli 0.8.3 → 0.9.1

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