urbanopt-cli 0.8.3 → 0.9.1

Sign up to get free protection for your applications and to get access to all the features.
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