urbanopt-cli 0.8.3 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (649) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -6
  3. data/CHANGELOG.md +14 -0
  4. data/CMakeLists.txt +7 -7
  5. data/Gemfile +3 -1
  6. data/README.md +9 -0
  7. data/example_files/Gemfile +23 -16
  8. data/example_files/Gemfile.lock +177 -0
  9. data/example_files/base_workflow_res.osw +57 -14
  10. data/example_files/class_project_coincident.json +1322 -0
  11. data/example_files/class_project_diverse.json +1322 -0
  12. data/example_files/disco/config.json +42 -0
  13. data/example_files/disco/cost_database.xlsx +0 -0
  14. data/example_files/disco/technical_catalog.json +12126 -0
  15. data/example_files/mappers/Baseline.rb +10 -7
  16. data/example_files/mappers/ChilledWaterStorage.rb +98 -0
  17. data/example_files/mappers/ClassProject.rb +110 -0
  18. data/example_files/mappers/CreateBar.rb +1 -0
  19. data/example_files/mappers/HighEfficiency.rb +13 -11
  20. data/example_files/mappers/PeakHoursMelsShedding.rb +72 -0
  21. data/example_files/mappers/PeakHoursThermostatAdjust.rb +78 -0
  22. data/example_files/mappers/ThermalStorage.rb +1 -0
  23. data/example_files/mappers/base_workflow.osw +55 -14
  24. data/example_files/mappers/class_project_workflow.osw +328 -0
  25. data/example_files/mappers/createbar_workflow.osw +16 -16
  26. data/example_files/measures/BuildResidentialModel/measure.rb +7 -1
  27. data/example_files/measures/BuildResidentialModel/measure.xml +1313 -706
  28. data/example_files/opendss/electrical_database.json +1446 -1446
  29. data/example_files/python_deps/dependencies.json +5 -0
  30. data/example_files/python_deps/install_python.ps1 +96 -0
  31. data/example_files/python_deps/install_python.sh +120 -0
  32. data/example_files/residential/clothes_dryer.tsv +11 -11
  33. data/example_files/residential/clothes_washer.tsv +3 -3
  34. data/example_files/residential/dishwasher.tsv +3 -3
  35. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +0 -1
  36. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +8 -21
  37. data/example_files/resources/hpxml-measures/.gitignore +2 -0
  38. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +1272 -1094
  39. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +978 -659
  40. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +52 -74
  41. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +77 -140
  42. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.rb +30 -27
  43. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml +32 -13
  44. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb +55 -51
  45. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/tests/build_residential_schedule_file_test.rb +89 -16
  46. data/example_files/resources/hpxml-measures/Changelog.md +65 -0
  47. data/example_files/resources/hpxml-measures/Gemfile +2 -4
  48. data/example_files/resources/hpxml-measures/Gemfile.lock +2 -13
  49. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +276 -300
  50. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +221 -215
  51. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +215 -170
  52. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/battery.rb +108 -16
  53. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +24 -44
  54. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +564 -197
  55. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/cambium/README.md +8 -8
  56. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +1 -0
  57. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +7 -55
  58. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +24 -19
  59. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +541 -211
  60. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +300 -172
  61. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXML.xsd +0 -2
  62. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLBaseElements.xsd +230 -141
  63. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLDataTypes.xsd +145 -137
  64. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml +191 -97
  65. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/iso-schematron.xsd +391 -0
  66. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +194 -198
  67. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +140 -145
  68. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +11 -11
  69. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +33 -1
  70. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb +4 -4
  71. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +17 -9
  72. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +14 -12
  73. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/output.rb +39 -17
  74. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/psychrometrics.rb +1 -1
  75. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/battery.csv +8761 -0
  76. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +114 -57
  77. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +1 -0
  78. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb +148 -0
  79. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +2 -2
  80. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +85 -127
  81. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/weather.rb +26 -32
  82. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +2 -14
  83. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlvalidator.rb +67 -0
  84. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +117 -56
  85. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_battery.rb +141 -14
  86. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +453 -344
  87. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +124 -20
  88. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +1 -1
  89. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +28 -32
  90. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +172 -79
  91. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +54 -8
  92. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +3 -3
  93. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +4 -4
  94. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +7 -7
  95. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +1 -1
  96. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_schedules.rb +6 -9
  97. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +8 -8
  98. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +213 -95
  99. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +1 -10
  100. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_weather.rb +76 -0
  101. data/example_files/resources/hpxml-measures/README.md +2 -3
  102. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.rb +585 -287
  103. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.xml +304 -352
  104. data/example_files/resources/hpxml-measures/ReportSimulationOutput/tests/output_report_test.rb +404 -279
  105. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.rb +222 -501
  106. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.xml +137 -200
  107. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Annual Charge.json +649 -0
  108. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Monthly Charge.json +649 -0
  109. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json +647 -0
  110. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate Min Annual Charge.json +8776 -0
  111. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate Min Monthly Charge.json +8776 -0
  112. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json +8774 -0
  113. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate Min Annual Charge.json +659 -0
  114. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate Min Monthly Charge.json +659 -0
  115. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json +657 -0
  116. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate Min Annual Charge.json +670 -0
  117. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate Min Monthly Charge.json +670 -0
  118. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json +668 -0
  119. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate Min Annual Charge.json +655 -0
  120. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate Min Monthly Charge.json +655 -0
  121. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json +653 -0
  122. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/openei_rates.zip +0 -0
  123. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/Average_retail_price_of_electricity.csv +0 -0
  124. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/HouseholdConsumption.csv +0 -0
  125. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/NG_PRI_SUM_A_EPG0_PRS_DMCF_A.csv +0 -0
  126. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/PET_PRI_WFR_A_EPD2F_PRS_DPGAL_W.csv +0 -0
  127. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/PET_PRI_WFR_A_EPLLPA_PRS_DPGAL_W.csv +0 -0
  128. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/README.md +0 -0
  129. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/util.rb +506 -25
  130. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Contains Demand Charges.json +1312 -0
  131. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Invalid Fixed Charge Units.json +657 -0
  132. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Invalid Min Charge Units.json +659 -0
  133. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/JacksonElectricMemberCorp-ResidentialSeniorCitizenLowIncomeAssistance.json +681 -0
  134. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Missing Required Fields.json +54 -0
  135. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/data.csv +8761 -0
  136. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/utility_bills_test.rb +1006 -235
  137. data/example_files/resources/hpxml-measures/docs/source/conf.py +1 -1
  138. data/example_files/resources/hpxml-measures/docs/source/intro.rst +0 -1
  139. data/example_files/resources/hpxml-measures/docs/source/usage_instructions.rst +2 -2
  140. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +461 -261
  141. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +146 -152
  142. data/example_files/resources/hpxml-measures/tasks.rb +616 -802
  143. data/example_files/resources/hpxml-measures/workflow/real_homes/house001.xml +19 -11
  144. data/example_files/resources/hpxml-measures/workflow/real_homes/house002.xml +20 -12
  145. data/example_files/resources/hpxml-measures/workflow/real_homes/house003.xml +12 -7
  146. data/example_files/resources/hpxml-measures/workflow/real_homes/house004.xml +12 -7
  147. data/example_files/resources/hpxml-measures/workflow/real_homes/house005.xml +19 -11
  148. data/example_files/resources/hpxml-measures/workflow/real_homes/house006.xml +12 -7
  149. data/example_files/resources/hpxml-measures/workflow/real_homes/house007.xml +20 -12
  150. data/example_files/resources/hpxml-measures/workflow/real_homes/house008.xml +28 -16
  151. data/example_files/resources/hpxml-measures/workflow/real_homes/house009.xml +28 -17
  152. data/example_files/resources/hpxml-measures/workflow/real_homes/house010.xml +28 -16
  153. data/example_files/resources/hpxml-measures/workflow/real_homes/house011.xml +20 -12
  154. data/example_files/resources/hpxml-measures/workflow/real_homes/house012.xml +20 -12
  155. data/example_files/resources/hpxml-measures/workflow/real_homes/house013.xml +20 -12
  156. data/example_files/resources/hpxml-measures/workflow/real_homes/house014.xml +20 -12
  157. data/example_files/resources/hpxml-measures/workflow/real_homes/house015.xml +20 -12
  158. data/example_files/resources/hpxml-measures/workflow/real_homes/house016.xml +22 -12
  159. data/example_files/resources/hpxml-measures/workflow/real_homes/house017.xml +19 -11
  160. data/example_files/resources/hpxml-measures/workflow/real_homes/house018.xml +20 -12
  161. data/example_files/resources/hpxml-measures/workflow/real_homes/house019.xml +13 -7
  162. data/example_files/resources/hpxml-measures/workflow/real_homes/house020.xml +12 -7
  163. data/example_files/resources/hpxml-measures/workflow/real_homes/house021.xml +31 -16
  164. data/example_files/resources/hpxml-measures/workflow/real_homes/house022.xml +22 -12
  165. data/example_files/resources/hpxml-measures/workflow/real_homes/house023.xml +21 -12
  166. data/example_files/resources/hpxml-measures/workflow/real_homes/house024.xml +37 -22
  167. data/example_files/resources/hpxml-measures/workflow/real_homes/house025.xml +24 -12
  168. data/example_files/resources/hpxml-measures/workflow/real_homes/house026.xml +33 -21
  169. data/example_files/resources/hpxml-measures/workflow/real_homes/house027.xml +28 -16
  170. data/example_files/resources/hpxml-measures/workflow/real_homes/house028.xml +28 -16
  171. data/example_files/resources/hpxml-measures/workflow/real_homes/house029.xml +30 -17
  172. data/example_files/resources/hpxml-measures/workflow/real_homes/house030.xml +10 -7
  173. data/example_files/resources/hpxml-measures/workflow/real_homes/house031.xml +22 -11
  174. data/example_files/resources/hpxml-measures/workflow/real_homes/house032.xml +12 -7
  175. data/example_files/resources/hpxml-measures/workflow/real_homes/house033.xml +18 -12
  176. data/example_files/resources/hpxml-measures/workflow/real_homes/house034.xml +25 -16
  177. data/example_files/resources/hpxml-measures/workflow/real_homes/house035.xml +22 -12
  178. data/example_files/resources/hpxml-measures/workflow/real_homes/house036.xml +20 -12
  179. data/example_files/resources/hpxml-measures/workflow/real_homes/house037.xml +26 -17
  180. data/example_files/resources/hpxml-measures/workflow/real_homes/house038.xml +19 -11
  181. data/example_files/resources/hpxml-measures/workflow/real_homes/house039.xml +25 -16
  182. data/example_files/resources/hpxml-measures/workflow/real_homes/house040.xml +20 -12
  183. data/example_files/resources/hpxml-measures/workflow/real_homes/house041.xml +35 -21
  184. data/example_files/resources/hpxml-measures/workflow/real_homes/house042.xml +28 -17
  185. data/example_files/resources/hpxml-measures/workflow/real_homes/house043.xml +20 -12
  186. data/example_files/resources/hpxml-measures/workflow/real_homes/house044.xml +35 -21
  187. data/example_files/resources/hpxml-measures/workflow/real_homes/house045.xml +20 -12
  188. data/example_files/resources/hpxml-measures/workflow/real_homes/house046.xml +20 -13
  189. data/example_files/resources/hpxml-measures/workflow/real_homes/house047.xml +12 -9
  190. data/example_files/resources/hpxml-measures/workflow/real_homes/house048.xml +25 -14
  191. data/example_files/resources/hpxml-measures/workflow/real_homes/house049.xml +10 -7
  192. data/example_files/resources/hpxml-measures/workflow/real_homes/house050.xml +20 -11
  193. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +91 -88
  194. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +18 -7
  195. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +546 -535
  196. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +546 -535
  197. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +555 -544
  198. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +18 -7
  199. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +18 -7
  200. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +18 -7
  201. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +18 -7
  202. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil-location-miami-fl.xml +580 -569
  203. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +18 -7
  204. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane-location-portland-or.xml +580 -569
  205. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +18 -7
  206. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +18 -7
  207. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +7 -0
  208. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +17 -6
  209. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +7 -0
  210. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +18 -7
  211. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +18 -7
  212. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +18 -7
  213. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery-scheduled.xml +600 -0
  214. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery.xml +598 -587
  215. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml +494 -485
  216. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +606 -593
  217. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml +494 -485
  218. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-heated-space.xml +494 -485
  219. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml +494 -485
  220. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-calctype-operational.xml +480 -471
  221. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +464 -457
  222. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +496 -487
  223. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +466 -459
  224. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +518 -509
  225. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +513 -504
  226. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +445 -438
  227. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +476 -467
  228. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +443 -436
  229. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +446 -439
  230. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +494 -485
  231. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +445 -438
  232. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +476 -467
  233. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +446 -439
  234. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +494 -485
  235. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +489 -480
  236. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +499 -490
  237. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +491 -482
  238. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room-multiple-water-heaters.xml +510 -0
  239. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +495 -486
  240. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-multiple.xml +709 -695
  241. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +528 -519
  242. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +512 -503
  243. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +504 -495
  244. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +497 -488
  245. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +490 -481
  246. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +487 -478
  247. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached-2stories.xml +639 -628
  248. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached-atticroof-cathedral.xml +587 -580
  249. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached.xml +639 -628
  250. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-defaults.xml +539 -528
  251. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-loads-large-uncommon.xml +644 -633
  252. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-loads-large-uncommon2.xml +644 -633
  253. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational.xml +575 -564
  254. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +16 -7
  255. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +16 -7
  256. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +18 -7
  257. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +585 -574
  258. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +18 -7
  259. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +18 -7
  260. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +18 -7
  261. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +18 -7
  262. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +18 -7
  263. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-detailed-setpoints.xml +536 -0
  264. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +16 -7
  265. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +16 -7
  266. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +20 -8
  267. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +16 -7
  268. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +16 -7
  269. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +18 -7
  270. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +18 -7
  271. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +18 -7
  272. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +16 -7
  273. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +18 -7
  274. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +16 -7
  275. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +18 -7
  276. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +19 -8
  277. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +19 -8
  278. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +19 -8
  279. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +19 -8
  280. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +19 -8
  281. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +18 -7
  282. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +18 -7
  283. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +18 -7
  284. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +18 -7
  285. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +18 -7
  286. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +18 -7
  287. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +18 -7
  288. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-detailed-setpoints.xml +582 -571
  289. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +583 -572
  290. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +18 -7
  291. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef-fhr.xml +584 -573
  292. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +584 -573
  293. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +18 -7
  294. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-detailed-schedules.xml +583 -572
  295. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-operating-mode-heat-pump-only.xml +585 -574
  296. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +18 -7
  297. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +582 -571
  298. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +18 -7
  299. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +18 -7
  300. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +18 -7
  301. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified-detailed-occupancy-stochastic.xml +586 -575
  302. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified.xml +585 -574
  303. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +18 -7
  304. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +18 -7
  305. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-detailed-setpoints.xml +580 -569
  306. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +18 -7
  307. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +580 -569
  308. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +18 -7
  309. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +580 -569
  310. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +18 -7
  311. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +18 -7
  312. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +18 -7
  313. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +18 -7
  314. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +28 -11
  315. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +20 -7
  316. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +18 -7
  317. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +18 -7
  318. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +18 -7
  319. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +18 -7
  320. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-ceilingtypes.xml +607 -0
  321. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-floortypes.xml +550 -0
  322. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +27 -12
  323. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +18 -7
  324. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +18 -7
  325. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +18 -7
  326. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +18 -7
  327. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +18 -7
  328. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-orientations.xml +589 -578
  329. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +18 -7
  330. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +18 -7
  331. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-physical-properties.xml +619 -608
  332. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +620 -609
  333. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-storms.xml +618 -607
  334. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +18 -7
  335. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +537 -526
  336. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +90 -43
  337. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +2507 -2460
  338. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-thermal-mass.xml +595 -584
  339. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +19 -8
  340. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-natural-ventilation-availability.xml +584 -0
  341. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +18 -7
  342. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-physical-properties.xml +594 -583
  343. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading.xml +597 -586
  344. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-storms.xml +598 -587
  345. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +27 -12
  346. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +671 -656
  347. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +18 -7
  348. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +18 -7
  349. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-foundation-conditioned-basement-wall-interior-insulation.xml → base-foundation-conditioned-basement-wall-insulation.xml} +585 -574
  350. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-crawlspace.xml +582 -571
  351. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +35 -16
  352. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +18 -7
  353. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +27 -12
  354. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +27 -12
  355. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +27 -12
  356. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +27 -12
  357. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +27 -12
  358. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +27 -12
  359. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +18 -7
  360. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-backup-lockout-temperature.xml +586 -575
  361. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +573 -562
  362. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +580 -569
  363. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-seer2-hspf2.xml +583 -0
  364. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +18 -7
  365. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +18 -7
  366. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-switchover-temperature.xml +600 -589
  367. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml +599 -588
  368. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-furnace.xml +629 -616
  369. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +18 -7
  370. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +573 -562
  371. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +579 -568
  372. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +581 -570
  373. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +581 -570
  374. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload-miami-fl.xml +582 -0
  375. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +581 -570
  376. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-acca.xml +581 -570
  377. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-hers.xml +581 -570
  378. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-maxload.xml +581 -570
  379. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler.xml +598 -587
  380. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-furnace.xml +628 -615
  381. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-acca.xml +581 -570
  382. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-hers.xml +581 -570
  383. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-maxload.xml +581 -570
  384. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-elec-only.xml +535 -526
  385. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-central-ac-1-speed.xml +589 -578
  386. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-only.xml +536 -527
  387. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-1-speed.xml +18 -7
  388. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-2-speed.xml +565 -554
  389. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-var-speed.xml +565 -554
  390. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-plus-air-to-air-heat-pump-heating.xml +18 -7
  391. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +582 -571
  392. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +582 -571
  393. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +582 -571
  394. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted.xml +18 -7
  395. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-elec-resistance-only.xml +526 -517
  396. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-evap-cooler-furnace-gas.xml +573 -562
  397. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-floor-furnace-propane-only.xml +529 -520
  398. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-elec-only.xml +565 -554
  399. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-2-speed.xml +580 -569
  400. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-var-speed.xml +580 -569
  401. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +565 -554
  402. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-room-ac.xml +578 -567
  403. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +575 -564
  404. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +581 -570
  405. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-acca.xml +583 -572
  406. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-hers.xml +583 -572
  407. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-maxload.xml +583 -572
  408. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +18 -7
  409. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-cooling-only.xml +18 -7
  410. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-heating-only.xml +18 -7
  411. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-acca.xml +580 -569
  412. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-hers.xml +580 -569
  413. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-maxload.xml +580 -569
  414. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-stove.xml +551 -542
  415. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac-with-heating.xml +532 -530
  416. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac.xml +525 -516
  417. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-acca.xml +541 -532
  418. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-hers.xml +541 -532
  419. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-maxload.xml +541 -532
  420. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-only.xml +525 -516
  421. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-heating.xml +533 -0
  422. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-acca.xml +542 -0
  423. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-hers.xml +542 -0
  424. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-maxload.xml +542 -0
  425. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-stove-oil-only.xml +529 -520
  426. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-wall-furnace-elec-only.xml +529 -520
  427. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize.xml +580 -569
  428. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +16 -7
  429. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +16 -7
  430. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +18 -7
  431. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +16 -7
  432. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +16 -7
  433. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +16 -7
  434. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +16 -7
  435. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed-seer2.xml +567 -0
  436. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +18 -7
  437. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +18 -7
  438. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +18 -7
  439. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +18 -7
  440. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +16 -7
  441. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml +18 -7
  442. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +18 -7
  443. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +18 -7
  444. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +18 -7
  445. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +18 -7
  446. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-fractions.xml +611 -598
  447. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-multipliers.xml +589 -0
  448. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-cfm50.xml +582 -571
  449. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +18 -7
  450. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +16 -7
  451. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +18 -7
  452. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +17 -7
  453. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +16 -7
  454. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +530 -521
  455. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +530 -521
  456. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +530 -521
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +566 -555
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +18 -7
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +18 -7
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +18 -7
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +18 -7
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-detailed-setpoints.xml +566 -555
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +566 -555
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +18 -7
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +18 -7
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +18 -7
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +18 -7
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +16 -7
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +574 -563
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +581 -570
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +583 -572
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml +587 -576
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml +587 -576
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-var-speed.xml +587 -576
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-1-speed.xml +591 -580
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-2-speed.xml +591 -580
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-var-speed.xml +591 -580
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-only.xml +570 -559
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-ground-to-air-heat-pump.xml +586 -575
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-air-conditioner-only-ducted.xml +570 -559
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-heat-pump-ducted.xml +586 -575
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +18 -7
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +16 -7
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +18 -7
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +18 -7
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +18 -7
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-stove.xml +552 -543
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +16 -7
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +963 -938
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +33 -69
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +530 -521
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-electricity.xml +535 -0
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-ptac-with-heating.xml → base-hvac-ptac-with-heating-natural-gas.xml} +23 -21
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac.xml +526 -517
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp.xml +541 -532
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +16 -7
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-ceer.xml +526 -517
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-detailed-setpoints.xml +526 -517
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +16 -7
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-heating.xml +535 -0
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-reverse-cycle.xml +542 -0
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-seasons.xml +594 -583
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-schedules.xml +586 -575
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-setbacks.xml +18 -7
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +18 -7
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +530 -521
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +530 -521
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +18 -7
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +18 -7
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +530 -521
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +18 -7
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-holiday.xml +18 -7
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +18 -7
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +18 -7
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +27 -12
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-capetown-zaf.xml +591 -576
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +18 -7
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +27 -12
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +582 -571
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +537 -526
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +18 -7
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +537 -526
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +601 -586
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +18 -7
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +18 -7
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-airflow-fraction-zero.xml +601 -587
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +19 -7
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +20 -7
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-exhaust.xml +607 -0
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-supply.xml +607 -0
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +21 -7
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +18 -7
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +18 -7
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +18 -7
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +18 -7
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +18 -7
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +18 -7
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +37 -19
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +18 -7
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +18 -7
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-additional-properties.xml +590 -579
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-none.xml +578 -0
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-detailed-only.xml +632 -0
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-mixed.xml +614 -0
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv.xml +677 -0
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills.xml +593 -0
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +27 -9
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-emissions.xml +676 -665
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery-scheduled.xml +616 -0
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery.xml +615 -0
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +598 -587
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-ground-conductivity.xml +586 -0
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +18 -7
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +18 -7
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +18 -7
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +18 -7
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +583 -572
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +18 -7
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +1700 -1677
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-ah.xml +622 -611
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-garage.xml +697 -682
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-pv-battery-lifetime-model.xml → base-pv-battery-round-trip-efficiency.xml} +20 -11
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-scheduled.xml +624 -0
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery.xml +622 -611
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery-scheduled.xml +640 -0
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery.xml +639 -0
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators.xml +623 -0
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +606 -595
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-all-10-mins.xml +582 -571
  570. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-smooth.xml +583 -572
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-10-mins.xml +584 -0
  572. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-vacancy.xml +583 -572
  573. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic.xml +583 -572
  574. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-schedules.xml +581 -570
  575. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-setbacks.xml +581 -570
  576. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints.xml +581 -570
  577. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple.xml +636 -625
  578. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +18 -7
  579. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +27 -14
  580. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +21 -10
  581. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +21 -10
  582. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-dhw-tank-heat-pump-detailed-operating-modes.xml → base-simcontrol-temperature-capacitance-multiplier.xml} +25 -13
  583. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-10-mins.xml +584 -0
  584. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-60-mins.xml +584 -0
  585. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +18 -7
  586. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-dhw-tank-heat-pump-detailed-setpoints.xml → base-simcontrol-timestep-30-mins.xml} +25 -14
  587. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +18 -7
  588. data/example_files/resources/hpxml-measures/workflow/template-build-and-run-hpxml-with-stochastic-occupancy.osw +18 -13
  589. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy.osw +12 -7
  590. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml.osw +8 -24
  591. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +366 -358
  592. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +369 -361
  593. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +369 -361
  594. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +369 -361
  595. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +369 -361
  596. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +369 -361
  597. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +369 -361
  598. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +369 -361
  599. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +311 -303
  600. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +311 -303
  601. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +327 -319
  602. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +327 -319
  603. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +332 -324
  604. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +332 -324
  605. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +341 -333
  606. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +341 -333
  607. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +369 -361
  608. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +369 -361
  609. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +369 -361
  610. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +369 -361
  611. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +369 -361
  612. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +369 -361
  613. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +383 -379
  614. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +383 -379
  615. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +538 -534
  616. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +550 -546
  617. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +444 -410
  618. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_ashrae_140.csv +8 -8
  619. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_bills.csv +444 -410
  620. data/example_files/resources/hpxml-measures/workflow/tests/compare.py +18 -4
  621. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +133 -288
  622. data/example_files/scripts/convert_urbanopt_to_disco.py +130 -0
  623. data/example_files/scripts/default_control_changes.csv +8 -0
  624. data/example_files/scripts/default_voltage_regulators.csv +3 -0
  625. data/example_files/scripts/read_data.py +331 -0
  626. data/example_files/visualization/input_visualization_feature.html +172 -81
  627. data/example_files/visualization/input_visualization_scenario.html +178 -82
  628. data/example_files/xml_building/17/README.md +2 -2
  629. data/example_files/xml_building/17/unit 1.xml +40 -41
  630. data/example_files/xml_building/17/unit 2.xml +35 -36
  631. data/example_files/xml_building/17/unit 3.xml +35 -36
  632. data/example_files/xml_building/17/unit 4.xml +41 -42
  633. data/lib/uo_cli/version.rb +1 -1
  634. data/lib/uo_cli.rb +596 -96
  635. data/uo_cli.gemspec +6 -5
  636. metadata +121 -36
  637. data/example_files/residential/exhaust.tsv +0 -3
  638. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/hvac_equipment_efficiency.csv +0 -493
  639. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/water_heater_efficiency.csv +0 -157
  640. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/HPXMLvalidator.xml +0 -620
  641. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/validator.rb +0 -107
  642. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.rb +0 -450
  643. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.xml +0 -85
  644. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/resources/constants.rb +0 -72
  645. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/tests/hpxml_output_report_test.rb +0 -290
  646. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_10kW.csv +0 -8761
  647. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_1kW.csv +0 -8761
  648. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_None.csv +0 -8761
  649. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_hvac_sizing.csv +0 -410
@@ -1,14 +1,16 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'oga'
4
- require_relative '../../HPXMLtoOpenStudio/resources/minitest_helper'
4
+ require_relative '../../HPXMLtoOpenStudio/resources/utility_bills'
5
5
  require_relative '../../HPXMLtoOpenStudio/resources/constants'
6
6
  require_relative '../../HPXMLtoOpenStudio/resources/energyplus'
7
7
  require_relative '../../HPXMLtoOpenStudio/resources/hpxml'
8
8
  require_relative '../../HPXMLtoOpenStudio/resources/hpxml_defaults'
9
+ require_relative '../../HPXMLtoOpenStudio/resources/minitest_helper'
9
10
  require_relative '../../HPXMLtoOpenStudio/resources/schedules'
10
11
  require_relative '../../HPXMLtoOpenStudio/resources/unit_conversions'
11
12
  require_relative '../../HPXMLtoOpenStudio/resources/xmlhelper'
13
+ require_relative '../../HPXMLtoOpenStudio/resources/version'
12
14
  require_relative '../resources/util.rb'
13
15
  require 'openstudio'
14
16
  require 'openstudio/measure/ShowRunnerOutput'
@@ -16,267 +18,330 @@ require_relative '../measure.rb'
16
18
  require 'csv'
17
19
 
18
20
  class ReportUtilityBillsTest < MiniTest::Test
19
- # BEopt 2.8.0.0:
21
+ # BEopt 2.9.0.0:
20
22
  # - Standard, New Construction, Single-Family Detached
21
23
  # - 600 sq ft (30 x 20)
22
24
  # - EPW Location: USA_CO_Denver.Intl.AP.725650_TMY3.epw
23
25
  # - Cooking Range: Propane
24
26
  # - Water Heater: Oil Standard
25
27
  # - PV System: None, 1.0 kW, 10.0 kW
26
- # - Timestep: 10 min
27
- # - User-Specified rates (calculated using Constants.Auto):
28
- # - Electricity: 0.1195179675994109 $/kWh
29
- # - Natural Gas: 0.7468734851091381 $/therm
30
- # - Fuel Oil: 3.495346153846154 $/gal
31
- # - Propane: 2.4532692307692305 $/gal
28
+ # - Timestep: 60 min
29
+ # - User-Specified rates (calculated using default value):
30
+ # - Electricity: 0.1195179675994109 USD/kWh
31
+ # - Natural Gas: 0.7734017611590879 USD/therm
32
+ # - Fuel Oil: 3.495346153846154 USD/gal
33
+ # - Propane: 2.4532692307692305 USD/gal
34
+ # - Sample Tiered Rate
35
+ # - Tier 1: 150 Max kWh
36
+ # - Tier 2: 300 Max kWh
37
+ # - Sample Tiered Time-of-Use Rate
38
+ # - Tier 1: 150 Max kWh (Period 1 and 2)
39
+ # - Tier 2: 300 Max kWh (Period 2)
32
40
  # - All other options left at default values
33
- # Then retrieve 1.csv from output folder, copy it, rename it
41
+ # Then retrieve 1.csv from output folder
34
42
 
35
43
  def setup
36
44
  @args_hash = {}
37
- @args_hash['electricity_fixed_charge'] = 8.0
38
- @args_hash['electricity_marginal_rate'] = Constants.Auto
39
- @args_hash['natural_gas_fixed_charge'] = 8.0
40
- @args_hash['natural_gas_marginal_rate'] = Constants.Auto
41
- @args_hash['fuel_oil_marginal_rate'] = Constants.Auto
42
- @args_hash['propane_marginal_rate'] = Constants.Auto
43
- @args_hash['wood_cord_marginal_rate'] = 0.015
44
- @args_hash['wood_pellets_marginal_rate'] = 0.015
45
- @args_hash['coal_marginal_rate'] = 0.015
46
- @args_hash['pv_compensation_type'] = 'Net Metering'
47
- @args_hash['pv_annual_excess_sellback_rate_type'] = 'User-Specified'
48
- @args_hash['pv_net_metering_annual_excess_sellback_rate'] = 0.03
49
- @args_hash['pv_feed_in_tariff_rate'] = 0.12
50
- @args_hash['pv_grid_connection_fee_units'] = '$/kW'
51
- @args_hash['pv_monthly_grid_connection_fee'] = 0.0
52
-
53
- # From BEopt Output screen (Utility Bills $/yr)
45
+
46
+ # From BEopt Output screen (Utility Bills USD/yr)
54
47
  @expected_bills = {
55
- 'Electricity: Fixed ($)' => 96,
56
- 'Electricity: Marginal ($)' => 629,
57
- 'Electricity: PV Credit ($)' => 0,
58
- 'Electricity: Total ($)' => 725,
59
- 'Natural Gas: Fixed ($)' => 96,
60
- 'Natural Gas: Marginal ($)' => 154,
61
- 'Natural Gas: Total ($)' => 250,
62
- 'Fuel Oil: Total ($)' => 462,
63
- 'Propane: Total ($)' => 76,
64
- 'Wood Cord: Total ($)' => 0,
65
- 'Wood Pellets: Total ($)' => 0,
66
- 'Coal: Total ($)' => 0,
67
- 'Total ($)' => 1514,
48
+ 'Test: Electricity: Fixed (USD)' => 96,
49
+ 'Test: Electricity: Energy (USD)' => 632,
50
+ 'Test: Electricity: PV Credit (USD)' => 0,
51
+ 'Test: Natural Gas: Fixed (USD)' => 96,
52
+ 'Test: Natural Gas: Energy (USD)' => 149,
53
+ 'Test: Fuel Oil: Fixed (USD)' => 0,
54
+ 'Test: Fuel Oil: Energy (USD)' => 462,
55
+ 'Test: Propane: Fixed (USD)' => 0,
56
+ 'Test: Propane: Energy (USD)' => 76,
57
+ 'Test: Coal: Fixed (USD)' => 0,
58
+ 'Test: Coal: Energy (USD)' => 0,
59
+ 'Test: Wood Cord: Fixed (USD)' => 0,
60
+ 'Test: Wood Cord: Energy (USD)' => 0,
61
+ 'Test: Wood Pellets: Fixed (USD)' => 0,
62
+ 'Test: Wood Pellets: Energy (USD)' => 0
68
63
  }
69
64
 
70
65
  @measure = ReportUtilityBills.new
71
- @hpxml = HPXML.new(hpxml_path: File.join(File.dirname(__FILE__), '../../workflow/sample_files/base-pv.xml'))
66
+ @hpxml_path = File.join(File.dirname(__FILE__), '../../workflow/sample_files/base-pv.xml')
67
+ @hpxml = HPXML.new(hpxml_path: @hpxml_path)
68
+ @hpxml.header.utility_bill_scenarios.clear
69
+ @hpxml.header.utility_bill_scenarios.add(name: 'Test',
70
+ elec_fixed_charge: 8.0,
71
+ natural_gas_fixed_charge: 8.0,
72
+ propane_marginal_rate: 2.4532692307692305,
73
+ fuel_oil_marginal_rate: 3.495346153846154)
74
+
75
+ # Check for presence of fuels once
76
+ has_fuel = {}
77
+ hpxml_doc = @hpxml.to_oga
78
+ Constants.FossilFuels.each do |fuel|
79
+ has_fuel[fuel] = @hpxml.has_fuel(fuel, hpxml_doc)
80
+ end
81
+
72
82
  HPXMLDefaults.apply_header(@hpxml, nil)
83
+ HPXMLDefaults.apply_utility_bill_scenarios(nil, @hpxml, has_fuel)
84
+
85
+ @root_path = File.absolute_path(File.join(File.dirname(__FILE__), '..', '..'))
86
+ @sample_files_path = File.join(@root_path, 'workflow', 'sample_files')
87
+ @tmp_hpxml_path = File.join(@sample_files_path, 'tmp.xml')
88
+ @bills_csv = File.join(File.dirname(__FILE__), 'results_bills.csv')
89
+
90
+ @fuels_pv_none_simple = _load_timeseries(0, false)
91
+ @fuels_pv_1kw_simple = _load_timeseries(1, false)
92
+ @fuels_pv_10kw_simple = _load_timeseries(10, false)
93
+ @fuels_pv_none_detailed = _load_timeseries(0, true)
94
+ @fuels_pv_1kw_detailed = _load_timeseries(1, true)
95
+ @fuels_pv_10kw_detailed = _load_timeseries(10, true)
73
96
  end
74
97
 
75
- def test_simple_calculations_pv_none
76
- fuels, utility_rates, utility_bills = @measure.setup_outputs()
77
- _load_timeseries(fuels, '../tests/PV_None.csv')
78
- bills_csv = _bill_calcs(fuels, utility_rates, utility_bills, @hpxml.header, [])
79
- assert(File.exist?(bills_csv))
80
- actual_bills = _get_actual_bills(bills_csv)
81
- _check_bills(@expected_bills, actual_bills)
98
+ def teardown
99
+ File.delete(@tmp_hpxml_path) if File.exist? @tmp_hpxml_path
100
+ File.delete(@bills_csv) if File.exist? @bills_csv
82
101
  end
83
102
 
84
- def test_simple_calculations_pv_1kW
85
- fuels, utility_rates, utility_bills = @measure.setup_outputs()
86
- _load_timeseries(fuels, '../tests/PV_1kW.csv')
87
- @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
88
- bills_csv = _bill_calcs(fuels, utility_rates, utility_bills, @hpxml.header, @hpxml.pv_systems)
89
- assert(File.exist?(bills_csv))
90
- actual_bills = _get_actual_bills(bills_csv)
91
- @expected_bills['Electricity: PV Credit ($)'] = -177
92
- @expected_bills['Electricity: Total ($)'] = 548
93
- @expected_bills['Total ($)'] = 1337
94
- _check_bills(@expected_bills, actual_bills)
103
+ # Simple (non-JSON) Calculations
104
+
105
+ def test_simple_pv_none
106
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
107
+ actual_bills = _bill_calcs(@fuels_pv_none_simple, @hpxml.header, [], utility_bill_scenario)
108
+ expected_bills = _get_expected_bills(@expected_bills)
109
+ _check_bills(expected_bills, actual_bills)
110
+ end
95
111
  end
96
112
 
97
- def test_simple_calculations_pv_10kW
98
- fuels, utility_rates, utility_bills = @measure.setup_outputs()
99
- _load_timeseries(fuels, '../tests/PV_10kW.csv')
100
- @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
101
- bills_csv = _bill_calcs(fuels, utility_rates, utility_bills, @hpxml.header, @hpxml.pv_systems)
102
- assert(File.exist?(bills_csv))
103
- actual_bills = _get_actual_bills(bills_csv)
104
- @expected_bills['Electricity: PV Credit ($)'] = -918
105
- @expected_bills['Electricity: Total ($)'] = -193
106
- @expected_bills['Total ($)'] = 596
107
- _check_bills(@expected_bills, actual_bills)
113
+ def test_simple_pv_1kW_net_metering_user_excess_rate
114
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
115
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
116
+ actual_bills = _bill_calcs(@fuels_pv_1kw_simple, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
117
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -177
118
+ expected_bills = _get_expected_bills(@expected_bills)
119
+ _check_bills(expected_bills, actual_bills)
120
+ end
108
121
  end
109
122
 
110
- def test_simple_calculations_pv_10kW_retail
111
- @args_hash['pv_annual_excess_sellback_rate_type'] = 'Retail Electricity Cost'
112
- fuels, utility_rates, utility_bills = @measure.setup_outputs()
113
- _load_timeseries(fuels, '../tests/PV_10kW.csv')
123
+ def test_simple_pv_10kW_net_metering_user_excess_rate
114
124
  @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
115
- bills_csv = _bill_calcs(fuels, utility_rates, utility_bills, @hpxml.header, @hpxml.pv_systems)
116
- assert(File.exist?(bills_csv))
117
- actual_bills = _get_actual_bills(bills_csv)
118
- @expected_bills['Electricity: PV Credit ($)'] = -1779
119
- @expected_bills['Electricity: Total ($)'] = -1054
120
- @expected_bills['Total ($)'] = -265
121
- _check_bills(@expected_bills, actual_bills)
125
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
126
+ actual_bills = _bill_calcs(@fuels_pv_10kw_simple, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
127
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -920
128
+ expected_bills = _get_expected_bills(@expected_bills)
129
+ _check_bills(expected_bills, actual_bills)
130
+ end
122
131
  end
123
132
 
124
- def test_simple_calculations_pv_1kW_feed_in_tariff
125
- @args_hash['pv_compensation_type'] = 'Feed-In Tariff'
126
- fuels, utility_rates, utility_bills = @measure.setup_outputs()
127
- _load_timeseries(fuels, '../tests/PV_1kW.csv')
128
- @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
129
- bills_csv = _bill_calcs(fuels, utility_rates, utility_bills, @hpxml.header, @hpxml.pv_systems)
130
- assert(File.exist?(bills_csv))
131
- actual_bills = _get_actual_bills(bills_csv)
132
- @expected_bills['Electricity: PV Credit ($)'] = -178
133
- @expected_bills['Electricity: Total ($)'] = 547
134
- @expected_bills['Total ($)'] = 1336
135
- _check_bills(@expected_bills, actual_bills)
133
+ def test_simple_pv_10kW_net_metering_retail_excess_rate
134
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate_type = HPXML::PVAnnualExcessSellbackRateTypeRetailElectricityCost
135
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
136
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
137
+ actual_bills = _bill_calcs(@fuels_pv_10kw_simple, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
138
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1777
139
+ expected_bills = _get_expected_bills(@expected_bills)
140
+ _check_bills(expected_bills, actual_bills)
141
+ end
136
142
  end
137
143
 
138
- def test_simple_calculations_pv_10kW_feed_in_tariff
139
- @args_hash['pv_compensation_type'] = 'Feed-In Tariff'
140
- fuels, utility_rates, utility_bills = @measure.setup_outputs()
141
- _load_timeseries(fuels, '../tests/PV_10kW.csv')
144
+ def test_simple_pv_10kW_net_metering_zero_excess_rate
145
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate = 0.0
142
146
  @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
143
- bills_csv = _bill_calcs(fuels, utility_rates, utility_bills, @hpxml.header, @hpxml.pv_systems)
144
- assert(File.exist?(bills_csv))
145
- actual_bills = _get_actual_bills(bills_csv)
146
- @expected_bills['Electricity: PV Credit ($)'] = -1787
147
- @expected_bills['Electricity: Total ($)'] = -1061
148
- @expected_bills['Total ($)'] = -272
149
- _check_bills(@expected_bills, actual_bills)
147
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
148
+ actual_bills = _bill_calcs(@fuels_pv_10kw_simple, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
149
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -632
150
+ expected_bills = _get_expected_bills(@expected_bills)
151
+ _check_bills(expected_bills, actual_bills)
152
+ end
150
153
  end
151
154
 
152
- def test_simple_calculations_pv_1kW_grid_fee_dollars_per_kW
153
- @args_hash['pv_monthly_grid_connection_fee'] = 2.50
154
- fuels, utility_rates, utility_bills = @measure.setup_outputs()
155
- _load_timeseries(fuels, '../tests/PV_1kW.csv')
155
+ def test_simple_pv_1kW_feed_in_tariff
156
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
157
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
156
158
  @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
157
- bills_csv = _bill_calcs(fuels, utility_rates, utility_bills, @hpxml.header, @hpxml.pv_systems)
158
- assert(File.exist?(bills_csv))
159
- actual_bills = _get_actual_bills(bills_csv)
160
- @expected_bills['Electricity: Fixed ($)'] = 126
161
- @expected_bills['Electricity: PV Credit ($)'] = -177
162
- @expected_bills['Electricity: Total ($)'] = 578
163
- @expected_bills['Total ($)'] = 1367
164
- _check_bills(@expected_bills, actual_bills)
165
- end
166
-
167
- def test_simple_calculations_pv_1kW_grid_fee_dollars
168
- @args_hash['pv_grid_connection_fee_units'] = '$'
169
- @args_hash['pv_monthly_grid_connection_fee'] = 7.50
170
- fuels, utility_rates, utility_bills = @measure.setup_outputs()
171
- _load_timeseries(fuels, '../tests/PV_1kW.csv')
172
- @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
173
- bills_csv = _bill_calcs(fuels, utility_rates, utility_bills, @hpxml.header, @hpxml.pv_systems)
174
- assert(File.exist?(bills_csv))
175
- actual_bills = _get_actual_bills(bills_csv)
176
- @expected_bills['Electricity: Fixed ($)'] = 186
177
- @expected_bills['Electricity: PV Credit ($)'] = -177
178
- @expected_bills['Electricity: Total ($)'] = 638
179
- @expected_bills['Total ($)'] = 1427
180
- _check_bills(@expected_bills, actual_bills)
159
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
160
+ actual_bills = _bill_calcs(@fuels_pv_1kw_simple, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
161
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -178
162
+ expected_bills = _get_expected_bills(@expected_bills)
163
+ _check_bills(expected_bills, actual_bills)
164
+ end
165
+ end
166
+
167
+ def test_simple_pv_10kW_feed_in_tariff
168
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
169
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
170
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
171
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
172
+ actual_bills = _bill_calcs(@fuels_pv_10kw_simple, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
173
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1785
174
+ expected_bills = _get_expected_bills(@expected_bills)
175
+ _check_bills(expected_bills, actual_bills)
176
+ end
181
177
  end
182
178
 
183
179
  def test_workflow_wood_cord
184
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-hvac-furnace-wood-only.xml'
185
- @args_hash['wood_cord_marginal_rate'] = 0.0500
186
- bills_csv = _test_measure()
187
- assert(File.exist?(bills_csv))
188
- actual_bills = _get_actual_bills(bills_csv)
189
- assert_operator(actual_bills['Wood Cord: Total ($)'], :>, 0)
180
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
181
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-hvac-furnace-wood-only.xml'))
182
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 1', wood_marginal_rate: 0.015)
183
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 2', wood_marginal_rate: 0.03)
184
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
185
+ actual_bills = _test_measure()
186
+ expected_val = actual_bills['Test 1: Wood Cord: Total (USD)']
187
+ assert_in_delta(expected_val * 2, actual_bills['Test 2: Wood Cord: Total (USD)'], 1)
190
188
  end
191
189
 
192
190
  def test_workflow_wood_pellets
193
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-hvac-stove-wood-pellets-only.xml'
194
- @args_hash['wood_pellets_marginal_rate'] = 0.0500
195
- bills_csv = _test_measure()
196
- assert(File.exist?(bills_csv))
197
- actual_bills = _get_actual_bills(bills_csv)
198
- assert_operator(actual_bills['Wood Pellets: Total ($)'], :>, 0)
191
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
192
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-hvac-stove-wood-pellets-only.xml'))
193
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 1', wood_pellets_marginal_rate: 0.02)
194
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 2', wood_pellets_marginal_rate: 0.01)
195
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
196
+ actual_bills = _test_measure()
197
+ expected_val = actual_bills['Test 1: Wood Pellets: Total (USD)']
198
+ assert_in_delta(expected_val / 2, actual_bills['Test 2: Wood Pellets: Total (USD)'], 1)
199
199
  end
200
200
 
201
201
  def test_workflow_coal
202
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-hvac-furnace-coal-only.xml'
203
- @args_hash['coal_marginal_rate'] = 0.0500
204
- bills_csv = _test_measure()
205
- assert(File.exist?(bills_csv))
206
- actual_bills = _get_actual_bills(bills_csv)
207
- assert_operator(actual_bills['Coal: Total ($)'], :>, 0)
202
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
203
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-hvac-furnace-coal-only.xml'))
204
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 1', coal_marginal_rate: 0.05)
205
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 2', coal_marginal_rate: 0.1)
206
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 3', coal_marginal_rate: 0.025)
207
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
208
+ actual_bills = _test_measure()
209
+ expected_val = actual_bills['Test 1: Coal: Total (USD)']
210
+ assert_in_delta(expected_val * 2, actual_bills['Test 2: Coal: Total (USD)'], 1)
211
+ assert_in_delta(expected_val / 2, actual_bills['Test 3: Coal: Total (USD)'], 1)
208
212
  end
209
213
 
210
214
  def test_workflow_leap_year
211
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-location-AMY-2012.xml'
212
- bills_csv = _test_measure()
213
- assert(File.exist?(bills_csv))
214
- actual_bills = _get_actual_bills(bills_csv)
215
- assert_operator(actual_bills['Total ($)'], :>, 0)
215
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
216
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-location-AMY-2012.xml'))
217
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
218
+ actual_bills = _test_measure()
219
+ assert_operator(actual_bills['Bills: Total (USD)'], :>, 0)
216
220
  end
217
221
 
218
222
  def test_workflow_semi_annual_run_period
219
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-simcontrol-runperiod-1-month.xml'
220
- bills_csv = _test_measure()
221
- assert(File.exist?(bills_csv))
222
- actual_bills = _get_actual_bills(bills_csv)
223
- assert_operator(actual_bills['Total ($)'], :>, 0)
223
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
224
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-simcontrol-runperiod-1-month.xml'))
225
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
226
+ actual_bills = _test_measure()
227
+ assert_operator(actual_bills['Bills: Total (USD)'], :>, 0)
228
+ end
229
+
230
+ def test_workflow_no_bill_scenarios
231
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
232
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-misc-bills-none.xml'))
233
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
234
+ actual_bills = _test_measure(hpxml: hpxml)
235
+ assert_nil(actual_bills)
236
+ end
237
+
238
+ def test_workflow_detailed_calculations
239
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
240
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base.xml'))
241
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 1', elec_tariff_filepath: '../../ReportUtilityBills/tests/JacksonElectricMemberCorp-ResidentialSeniorCitizenLowIncomeAssistance.json')
242
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
243
+ actual_bills = _test_measure()
244
+ assert_operator(actual_bills['Test 1: Total (USD)'], :>, 0)
224
245
  end
225
246
 
226
247
  def test_auto_marginal_rate
227
- fuel_types = [FT::Elec, FT::Gas, FT::Oil, FT::Propane]
248
+ fuel_types = [HPXML::FuelTypeElectricity, HPXML::FuelTypeNaturalGas, HPXML::FuelTypeOil, HPXML::FuelTypePropane]
228
249
 
229
250
  # Check that we can successfully look up "auto" rates for every state
230
251
  # and every fuel type.
231
- runner = OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new)
232
252
  Constants.StateCodesMap.keys.each do |state_code|
233
253
  fuel_types.each do |fuel_type|
234
- flatratebuy = @measure.get_auto_marginal_rate(runner, state_code, fuel_type, 0)
254
+ flatratebuy, _ = UtilityBills.get_rates_from_eia_data(nil, state_code, fuel_type, 0)
235
255
  refute_nil(flatratebuy)
236
256
  end
237
257
  end
238
258
 
259
+ # Check that we can successfully look up "auto" rates for the US too.
260
+ fuel_types.each do |fuel_type|
261
+ flatratebuy, _ = UtilityBills.get_rates_from_eia_data(nil, 'US', fuel_type, 0)
262
+ refute_nil(flatratebuy)
263
+ end
264
+
239
265
  # Check that any other state code is gracefully handled (no error)
240
266
  fuel_types.each do |fuel_type|
241
- flatratebuy = @measure.get_auto_marginal_rate(runner, 'XX', fuel_type, 0)
267
+ UtilityBills.get_rates_from_eia_data(nil, 'XX', fuel_type, 0)
242
268
  end
243
269
  end
244
270
 
245
271
  def test_warning_region
246
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-appliances-oil-location-miami-fl.xml'
247
- expected_warnings = ['Could not find state average Fuel Oil rate based on Florida; using region (PADD 1C) average.']
248
- bills_csv = _test_measure(expected_warnings: expected_warnings)
249
- assert(File.exist?(bills_csv))
272
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
273
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-appliances-oil-location-miami-fl.xml'))
274
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
275
+ expected_warnings = ['Could not find state average fuel oil rate based on Florida; using region (PADD 1C) average.']
276
+ actual_bills = _test_measure(expected_warnings: expected_warnings)
277
+ assert_nil(actual_bills)
250
278
  end
251
279
 
252
280
  def test_warning_national
253
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-appliances-propane-location-portland-or.xml'
254
- expected_warnings = ['Could not find state average Propane rate based on Oregon; using national average.']
255
- bills_csv = _test_measure(expected_warnings: expected_warnings)
256
- assert(File.exist?(bills_csv))
281
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
282
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-appliances-propane-location-portland-or.xml'))
283
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
284
+ expected_warnings = ['Could not find state average propane rate based on Oregon; using national average.']
285
+ actual_bills = _test_measure(expected_warnings: expected_warnings)
286
+ assert_nil(actual_bills)
257
287
  end
258
288
 
259
289
  def test_warning_dse
260
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-hvac-dse.xml'
290
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
291
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-hvac-dse.xml'))
292
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
261
293
  expected_warnings = ['DSE is not currently supported when calculating utility bills.']
262
- bills_csv = _test_measure(expected_warnings: expected_warnings)
263
- assert(!File.exist?(bills_csv))
294
+ actual_bills = _test_measure(expected_warnings: expected_warnings)
295
+ assert_nil(actual_bills)
264
296
  end
265
297
 
266
298
  def test_warning_no_rates
267
- @args_hash['hpxml_path'] = '../workflow/sample_files/base-location-capetown-zaf.xml'
299
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
300
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base-location-capetown-zaf.xml'))
301
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
268
302
  expected_warnings = ['Could not find a marginal Electricity rate.', 'Could not find a marginal Natural Gas rate.']
269
- bills_csv = _test_measure(expected_warnings: expected_warnings)
270
- assert(!File.exist?(bills_csv))
303
+ actual_bills = _test_measure(expected_warnings: expected_warnings)
304
+ assert_nil(actual_bills)
305
+ end
306
+
307
+ def test_warning_invalid_fixed_charge_units
308
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
309
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base.xml'))
310
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 1', elec_tariff_filepath: '../../ReportUtilityBills/tests/Invalid Fixed Charge Units.json')
311
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
312
+ expected_warnings = ['Fixed charge units must be $/month.']
313
+ actual_bills = _test_measure(expected_warnings: expected_warnings)
314
+ assert_nil(actual_bills)
271
315
  end
272
316
 
273
- def test_error_user_specified_but_no_rates
274
- skip
275
- @args_hash['electricity_bill_type'] = 'Detailed'
276
- @args_hash['electricity_utility_rate_type'] = 'User-Specified'
277
- expected_errors = ['Must specify a utility rate json path when choosing User-Specified utility rate type.']
278
- bills_csv = _test_measure(expected_errors: expected_errors)
279
- assert(!File.exist?(bills_csv))
317
+ def test_warning_invalid_min_charge_units
318
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
319
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base.xml'))
320
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 1', elec_tariff_filepath: '../../ReportUtilityBills/tests/Invalid Min Charge Units.json')
321
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
322
+ expected_warnings = ['Min charge units must be either $/month or $/year.']
323
+ actual_bills = _test_measure(expected_warnings: expected_warnings)
324
+ assert_nil(actual_bills)
325
+ end
326
+
327
+ def test_warning_demand_charges
328
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
329
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base.xml'))
330
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 1', elec_tariff_filepath: '../../ReportUtilityBills/tests/Contains Demand Charges.json')
331
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
332
+ expected_warnings = ['Demand charges are not currently supported when calculating detailed utility bills.']
333
+ actual_bills = _test_measure(expected_warnings: expected_warnings)
334
+ assert_nil(actual_bills)
335
+ end
336
+
337
+ def test_warning_missing_required_fields
338
+ @args_hash['hpxml_path'] = File.absolute_path(@tmp_hpxml_path)
339
+ hpxml = HPXML.new(hpxml_path: File.join(@sample_files_path, 'base.xml'))
340
+ hpxml.header.utility_bill_scenarios.add(name: 'Test 1', elec_tariff_filepath: '../../ReportUtilityBills/tests/Missing Required Fields.json')
341
+ XMLHelper.write_file(hpxml.to_oga, @tmp_hpxml_path)
342
+ expected_warnings = ['Tariff file must contain energyweekdayschedule, energyweekendschedule, and energyratestructure fields.']
343
+ actual_bills = _test_measure(expected_warnings: expected_warnings)
344
+ assert_nil(actual_bills)
280
345
  end
281
346
 
282
347
  def test_monthly_prorate
@@ -305,64 +370,724 @@ class ReportUtilityBillsTest < MiniTest::Test
305
370
  assert_equal(0.0, CalculateUtilityBill.calculate_monthly_prorate(header, 5))
306
371
  end
307
372
 
308
- def _check_bills(expected_bills, actual_bills)
309
- bills = expected_bills.keys | actual_bills.keys
310
- bills.each do |bill|
311
- assert(expected_bills.keys.include?(bill))
312
- assert(actual_bills.keys.include?(bill))
313
- assert_in_delta(expected_bills[bill], actual_bills[bill], 1) # within a dollar
373
+ # Detailed (JSON) Calculations
374
+
375
+ # Flat (Same as simple tests above)
376
+
377
+ def test_detailed_flat_pv_none
378
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
379
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
380
+ actual_bills = _bill_calcs(@fuels_pv_none_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
381
+ expected_bills = _get_expected_bills(@expected_bills)
382
+ _check_bills(expected_bills, actual_bills)
314
383
  end
315
384
  end
316
385
 
317
- def _get_actual_bills(bills_csv)
318
- actual_bills = {}
319
- File.readlines(bills_csv).each do |line|
320
- next if line.strip.empty?
386
+ def test_detailed_flat_pv_1kW_net_metering_user_excess_rate
387
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
388
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
389
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
390
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
391
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -177
392
+ expected_bills = _get_expected_bills(@expected_bills)
393
+ _check_bills(expected_bills, actual_bills)
394
+ end
395
+ end
321
396
 
322
- key, value = line.split(',').map { |x| x.strip }
323
- actual_bills[key] = Float(value)
397
+ def test_detailed_flat_pv_10kW_net_metering_user_excess_rate
398
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
399
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
400
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
401
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
402
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -920
403
+ expected_bills = _get_expected_bills(@expected_bills)
404
+ _check_bills(expected_bills, actual_bills)
405
+ end
406
+ end
407
+
408
+ def test_detailed_flat_pv_10kW_net_metering_retail_excess_rate
409
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
410
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate_type = HPXML::PVAnnualExcessSellbackRateTypeRetailElectricityCost
411
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
412
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
413
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
414
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1777
415
+ expected_bills = _get_expected_bills(@expected_bills)
416
+ _check_bills(expected_bills, actual_bills)
417
+ end
418
+ end
419
+
420
+ def test_detailed_flat_pv_10kW_net_metering_zero_excess_rate
421
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
422
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate = 0.0
423
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
424
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
425
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
426
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -632
427
+ expected_bills = _get_expected_bills(@expected_bills)
428
+ _check_bills(expected_bills, actual_bills)
429
+ end
430
+ end
431
+
432
+ def test_detailed_flat_pv_1kW_feed_in_tariff
433
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
434
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
435
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
436
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
437
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
438
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
439
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -178
440
+ expected_bills = _get_expected_bills(@expected_bills)
441
+ _check_bills(expected_bills, actual_bills)
442
+ end
443
+ end
444
+
445
+ def test_detailed_flat_pv_10kW_feed_in_tariff
446
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
447
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
448
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
449
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
450
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
451
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
452
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1785
453
+ expected_bills = _get_expected_bills(@expected_bills)
454
+ _check_bills(expected_bills, actual_bills)
455
+ end
456
+ end
457
+
458
+ # Tiered
459
+
460
+ def test_detailed_tiered_pv_none
461
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json'
462
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
463
+ actual_bills = _bill_calcs(@fuels_pv_none_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
464
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
465
+ @expected_bills['Test: Electricity: Energy (USD)'] = 580
466
+ expected_bills = _get_expected_bills(@expected_bills)
467
+ _check_bills(expected_bills, actual_bills)
468
+ end
469
+ end
470
+
471
+ def test_detailed_tiered_pv_1kW_net_metering_user_excess_rate
472
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json'
473
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
474
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
475
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
476
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
477
+ @expected_bills['Test: Electricity: Energy (USD)'] = 580
478
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -190
479
+ expected_bills = _get_expected_bills(@expected_bills)
480
+ _check_bills(expected_bills, actual_bills)
481
+ end
482
+ end
483
+
484
+ def test_detailed_tiered_pv_10kW_net_metering_user_excess_rate
485
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json'
486
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
487
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
488
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
489
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
490
+ @expected_bills['Test: Electricity: Energy (USD)'] = 580
491
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -867
492
+ expected_bills = _get_expected_bills(@expected_bills)
493
+ _check_bills(expected_bills, actual_bills)
494
+ end
495
+ end
496
+
497
+ def test_detailed_tiered_pv_10kW_net_metering_retail_excess_rate
498
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json'
499
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate_type = HPXML::PVAnnualExcessSellbackRateTypeRetailElectricityCost
500
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
501
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
502
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
503
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
504
+ @expected_bills['Test: Electricity: Energy (USD)'] = 580
505
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1443
506
+ expected_bills = _get_expected_bills(@expected_bills)
507
+ _check_bills(expected_bills, actual_bills)
324
508
  end
325
- return actual_bills
326
509
  end
327
510
 
328
- def _load_timeseries(fuels, path)
329
- columns = CSV.read(File.join(File.dirname(__FILE__), path)).transpose
511
+ def test_detailed_tiered_pv_10kW_net_metering_zero_excess_rate
512
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate = 0.0
513
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json'
514
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
515
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
516
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
517
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
518
+ @expected_bills['Test: Electricity: Energy (USD)'] = 580
519
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -580
520
+ expected_bills = _get_expected_bills(@expected_bills)
521
+ _check_bills(expected_bills, actual_bills)
522
+ end
523
+ end
524
+
525
+ def test_detailed_tiered_pv_1kW_feed_in_tariff
526
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json'
527
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
528
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
529
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
530
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
531
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
532
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
533
+ @expected_bills['Test: Electricity: Energy (USD)'] = 580
534
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -178
535
+ expected_bills = _get_expected_bills(@expected_bills)
536
+ _check_bills(expected_bills, actual_bills)
537
+ end
538
+ end
539
+
540
+ def test_detailed_tiered_pv_10kW_feed_in_tariff
541
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json'
542
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
543
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
544
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
545
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
546
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
547
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
548
+ @expected_bills['Test: Electricity: Energy (USD)'] = 580
549
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1785
550
+ expected_bills = _get_expected_bills(@expected_bills)
551
+ _check_bills(expected_bills, actual_bills)
552
+ end
553
+ end
554
+
555
+ # Time-of-Use
556
+
557
+ def test_detailed_tou_pv_none
558
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json'
559
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
560
+ actual_bills = _bill_calcs(@fuels_pv_none_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
561
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
562
+ @expected_bills['Test: Electricity: Energy (USD)'] = 393
563
+ expected_bills = _get_expected_bills(@expected_bills)
564
+ _check_bills(expected_bills, actual_bills)
565
+ end
566
+ end
567
+
568
+ def test_detailed_tou_pv_1kW_net_metering_user_excess_rate
569
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json'
570
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
571
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
572
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
573
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
574
+ @expected_bills['Test: Electricity: Energy (USD)'] = 393
575
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -112
576
+ expected_bills = _get_expected_bills(@expected_bills)
577
+ _check_bills(expected_bills, actual_bills)
578
+ end
579
+ end
580
+
581
+ def test_detailed_tou_pv_10kW_net_metering_user_excess_rate
582
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json'
583
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
584
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
585
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
586
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
587
+ @expected_bills['Test: Electricity: Energy (USD)'] = 393
588
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -681
589
+ expected_bills = _get_expected_bills(@expected_bills)
590
+ _check_bills(expected_bills, actual_bills)
591
+ end
592
+ end
593
+
594
+ def test_detailed_tou_pv_10kW_net_metering_retail_excess_rate
595
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json'
596
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate_type = HPXML::PVAnnualExcessSellbackRateTypeRetailElectricityCost
597
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
598
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
599
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
600
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
601
+ @expected_bills['Test: Electricity: Energy (USD)'] = 393
602
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1127
603
+ expected_bills = _get_expected_bills(@expected_bills)
604
+ _check_bills(expected_bills, actual_bills)
605
+ end
606
+ end
607
+
608
+ def test_detailed_tou_pv_10kW_net_metering_zero_excess_rate
609
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate = 0.0
610
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json'
611
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
612
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
613
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
614
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
615
+ @expected_bills['Test: Electricity: Energy (USD)'] = 393
616
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -393
617
+ expected_bills = _get_expected_bills(@expected_bills)
618
+ _check_bills(expected_bills, actual_bills)
619
+ end
620
+ end
621
+
622
+ def test_detailed_tou_pv_1kW_feed_in_tariff
623
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json'
624
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
625
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
626
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
627
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
628
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
629
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
630
+ @expected_bills['Test: Electricity: Energy (USD)'] = 393
631
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -178
632
+ expected_bills = _get_expected_bills(@expected_bills)
633
+ _check_bills(expected_bills, actual_bills)
634
+ end
635
+ end
636
+
637
+ def test_detailed_tou_pv_10kW_feed_in_tariff
638
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json'
639
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
640
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
641
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
642
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
643
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
644
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
645
+ @expected_bills['Test: Electricity: Energy (USD)'] = 393
646
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1785
647
+ expected_bills = _get_expected_bills(@expected_bills)
648
+ _check_bills(expected_bills, actual_bills)
649
+ end
650
+ end
651
+
652
+ # Tiered and Time-of-Use
653
+
654
+ def test_detailed_tiered_tou_pv_none
655
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json'
656
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
657
+ actual_bills = _bill_calcs(@fuels_pv_none_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
658
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
659
+ @expected_bills['Test: Electricity: Energy (USD)'] = 377
660
+ expected_bills = _get_expected_bills(@expected_bills)
661
+ _check_bills(expected_bills, actual_bills)
662
+ end
663
+ end
664
+
665
+ def test_detailed_tiered_tou_pv_1kW_net_metering_user_excess_rate
666
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json'
667
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
668
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
669
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
670
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
671
+ @expected_bills['Test: Electricity: Energy (USD)'] = 377
672
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -108
673
+ expected_bills = _get_expected_bills(@expected_bills)
674
+ _check_bills(expected_bills, actual_bills)
675
+ end
676
+ end
677
+
678
+ def test_detailed_tiered_tou_pv_10kW_net_metering_user_excess_rate
679
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json'
680
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
681
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
682
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
683
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
684
+ @expected_bills['Test: Electricity: Energy (USD)'] = 377
685
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -665
686
+ expected_bills = _get_expected_bills(@expected_bills)
687
+ _check_bills(expected_bills, actual_bills)
688
+ end
689
+ end
690
+
691
+ def test_detailed_tiered_tou_pv_10kW_net_metering_retail_excess_rate
692
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json'
693
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate_type = HPXML::PVAnnualExcessSellbackRateTypeRetailElectricityCost
694
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
695
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
696
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
697
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
698
+ @expected_bills['Test: Electricity: Energy (USD)'] = 377
699
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1000
700
+ expected_bills = _get_expected_bills(@expected_bills)
701
+ _check_bills(expected_bills, actual_bills)
702
+ end
703
+ end
704
+
705
+ def test_detailed_tiered_tou_pv_10kW_net_metering_zero_excess_rate
706
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate = 0.0
707
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json'
708
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
709
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
710
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
711
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
712
+ @expected_bills['Test: Electricity: Energy (USD)'] = 377
713
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -377
714
+ expected_bills = _get_expected_bills(@expected_bills)
715
+ _check_bills(expected_bills, actual_bills)
716
+ end
717
+ end
718
+
719
+ def test_detailed_tiered_tou_pv_1kW_feed_in_tariff
720
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json'
721
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
722
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
723
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
724
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
725
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
726
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
727
+ @expected_bills['Test: Electricity: Energy (USD)'] = 377
728
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -178
729
+ expected_bills = _get_expected_bills(@expected_bills)
730
+ _check_bills(expected_bills, actual_bills)
731
+ end
732
+ end
733
+
734
+ def test_detailed_tiered_tou_pv_10kW_feed_in_tariff
735
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json'
736
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
737
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
738
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
739
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
740
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
741
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
742
+ @expected_bills['Test: Electricity: Energy (USD)'] = 377
743
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1785
744
+ expected_bills = _get_expected_bills(@expected_bills)
745
+ _check_bills(expected_bills, actual_bills)
746
+ end
747
+ end
748
+
749
+ # Real-time Pricing
750
+
751
+ def test_detailed_rtp_pv_none
752
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json'
753
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
754
+ actual_bills = _bill_calcs(@fuels_pv_none_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
755
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
756
+ @expected_bills['Test: Electricity: Energy (USD)'] = 354
757
+ expected_bills = _get_expected_bills(@expected_bills)
758
+ _check_bills(expected_bills, actual_bills)
759
+ end
760
+ end
761
+
762
+ def test_detailed_rtp_pv_1kW_net_metering_user_excess_rate
763
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json'
764
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
765
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
766
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
767
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
768
+ @expected_bills['Test: Electricity: Energy (USD)'] = 354
769
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -106
770
+ expected_bills = _get_expected_bills(@expected_bills)
771
+ _check_bills(expected_bills, actual_bills)
772
+ end
773
+ end
774
+
775
+ def test_detailed_rtp_pv_10kW_net_metering_user_excess_rate
776
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json'
777
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
778
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
779
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
780
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
781
+ @expected_bills['Test: Electricity: Energy (USD)'] = 354
782
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -641
783
+ expected_bills = _get_expected_bills(@expected_bills)
784
+ _check_bills(expected_bills, actual_bills)
785
+ end
786
+ end
787
+
788
+ def test_detailed_rtp_pv_10kW_net_metering_retail_excess_rate
789
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json'
790
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate_type = HPXML::PVAnnualExcessSellbackRateTypeRetailElectricityCost
791
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
792
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
793
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
794
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
795
+ @expected_bills['Test: Electricity: Energy (USD)'] = 354
796
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1060
797
+ expected_bills = _get_expected_bills(@expected_bills)
798
+ _check_bills(expected_bills, actual_bills)
799
+ end
800
+ end
801
+
802
+ def test_detailed_rtp_pv_10kW_net_metering_zero_excess_rate
803
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate = 0.0
804
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json'
805
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
806
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
807
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
808
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
809
+ @expected_bills['Test: Electricity: Energy (USD)'] = 354
810
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -354
811
+ expected_bills = _get_expected_bills(@expected_bills)
812
+ _check_bills(expected_bills, actual_bills)
813
+ end
814
+ end
815
+
816
+ def test_detailed_rtp_pv_1kW_feed_in_tariff
817
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json'
818
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
819
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
820
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
821
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
822
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
823
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
824
+ @expected_bills['Test: Electricity: Energy (USD)'] = 354
825
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -178
826
+ expected_bills = _get_expected_bills(@expected_bills)
827
+ _check_bills(expected_bills, actual_bills)
828
+ end
829
+ end
830
+
831
+ def test_detailed_rtp_pv_10kW_feed_in_tariff
832
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json'
833
+ @hpxml.header.utility_bill_scenarios[-1].pv_compensation_type = HPXML::PVCompensationTypeFeedInTariff
834
+ @hpxml.header.utility_bill_scenarios[-1].pv_feed_in_tariff_rate = 0.12
835
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
836
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
837
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
838
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 108
839
+ @expected_bills['Test: Electricity: Energy (USD)'] = 354
840
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1785
841
+ expected_bills = _get_expected_bills(@expected_bills)
842
+ _check_bills(expected_bills, actual_bills)
843
+ end
844
+ end
845
+
846
+ # Extra Fees & Charges
847
+
848
+ def test_simple_pv_1kW_grid_fee_dollars_per_kW
849
+ @hpxml.header.utility_bill_scenarios[-1].pv_monthly_grid_connection_fee_dollars_per_kw = 2.50
850
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
851
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
852
+ actual_bills = _bill_calcs(@fuels_pv_1kw_simple, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
853
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 126
854
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -177
855
+ expected_bills = _get_expected_bills(@expected_bills)
856
+ _check_bills(expected_bills, actual_bills)
857
+ end
858
+ end
859
+
860
+ def test_simple_pv_1kW_grid_fee_dollars
861
+ @hpxml.header.utility_bill_scenarios[-1].pv_monthly_grid_connection_fee_dollars = 7.50
862
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
863
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
864
+ actual_bills = _bill_calcs(@fuels_pv_1kw_simple, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
865
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 186
866
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -177
867
+ expected_bills = _get_expected_bills(@expected_bills)
868
+ _check_bills(expected_bills, actual_bills)
869
+ end
870
+ end
871
+
872
+ def test_detailed_pv_1kW_grid_fee_dollars_per_kW
873
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
874
+ @hpxml.header.utility_bill_scenarios[-1].pv_monthly_grid_connection_fee_dollars_per_kw = 2.50
875
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
876
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
877
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
878
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 126
879
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -177
880
+ expected_bills = _get_expected_bills(@expected_bills)
881
+ _check_bills(expected_bills, actual_bills)
882
+ end
883
+ end
884
+
885
+ def test_detailed_pv_1kW_grid_fee_dollars
886
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json'
887
+ @hpxml.header.utility_bill_scenarios[-1].pv_monthly_grid_connection_fee_dollars = 7.50
888
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
889
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
890
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
891
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 186
892
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -177
893
+ expected_bills = _get_expected_bills(@expected_bills)
894
+ _check_bills(expected_bills, actual_bills)
895
+ end
896
+ end
897
+
898
+ def test_detailed_pv_none_min_monthly_charge
899
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Monthly Charge.json'
900
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
901
+ actual_bills = _bill_calcs(@fuels_pv_none_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
902
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 96
903
+ @expected_bills['Test: Electricity: Energy (USD)'] = 632
904
+ expected_bills = _get_expected_bills(@expected_bills)
905
+ _check_bills(expected_bills, actual_bills)
906
+ end
907
+ end
908
+
909
+ def test_detailed_pv_none_min_annual_charge
910
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Annual Charge.json'
911
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
912
+ actual_bills = _bill_calcs(@fuels_pv_none_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
913
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 96
914
+ @expected_bills['Test: Electricity: Energy (USD)'] = 632
915
+ expected_bills = _get_expected_bills(@expected_bills)
916
+ _check_bills(expected_bills, actual_bills)
917
+ end
918
+ end
919
+
920
+ def test_detailed_pv_1kW_net_metering_user_excess_rate_min_monthly_charge
921
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Monthly Charge.json'
922
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
923
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
924
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
925
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 96
926
+ @expected_bills['Test: Electricity: Energy (USD)'] = 632
927
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -177
928
+ expected_bills = _get_expected_bills(@expected_bills)
929
+ _check_bills(expected_bills, actual_bills)
930
+ end
931
+ end
932
+
933
+ def test_detailed_pv_1kW_net_metering_user_excess_rate_min_annual_charge
934
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Annual Charge.json'
935
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 1000.0 / @hpxml.pv_systems.size }
936
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
937
+ actual_bills = _bill_calcs(@fuels_pv_1kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
938
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 96
939
+ @expected_bills['Test: Electricity: Energy (USD)'] = 632
940
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -177
941
+ expected_bills = _get_expected_bills(@expected_bills)
942
+ _check_bills(expected_bills, actual_bills)
943
+ end
944
+ end
945
+
946
+ def test_detailed_pv_10kW_net_metering_user_excess_rate_min_monthly_charge
947
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Monthly Charge.json'
948
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
949
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
950
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
951
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 180
952
+ @expected_bills['Test: Electricity: Energy (USD)'] = 632
953
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -920
954
+ expected_bills = _get_expected_bills(@expected_bills)
955
+ _check_bills(expected_bills, actual_bills)
956
+ end
957
+ end
958
+
959
+ def test_detailed_pv_10kW_net_metering_user_excess_rate_min_annual_charge
960
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Annual Charge.json'
961
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
962
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
963
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
964
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 200
965
+ @expected_bills['Test: Electricity: Energy (USD)'] = 632
966
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -920
967
+ expected_bills = _get_expected_bills(@expected_bills)
968
+ _check_bills(expected_bills, actual_bills)
969
+ end
970
+ end
971
+
972
+ def test_detailed_pv_10kW_net_metering_retail_excess_rate_min_monthly_charge
973
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Monthly Charge.json'
974
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate_type = HPXML::PVAnnualExcessSellbackRateTypeRetailElectricityCost
975
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
976
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
977
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
978
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 180
979
+ @expected_bills['Test: Electricity: Energy (USD)'] = 632
980
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1777
981
+ expected_bills = _get_expected_bills(@expected_bills)
982
+ _check_bills(expected_bills, actual_bills)
983
+ end
984
+ end
985
+
986
+ def test_detailed_pv_10kW_net_metering_retail_excess_rate_min_annual_charge
987
+ @hpxml.header.utility_bill_scenarios[-1].elec_tariff_filepath = '../../ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Annual Charge.json'
988
+ @hpxml.header.utility_bill_scenarios[-1].pv_net_metering_annual_excess_sellback_rate_type = HPXML::PVAnnualExcessSellbackRateTypeRetailElectricityCost
989
+ @hpxml.pv_systems.each { |pv_system| pv_system.max_power_output = 10000.0 / @hpxml.pv_systems.size }
990
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
991
+ actual_bills = _bill_calcs(@fuels_pv_10kw_detailed, @hpxml.header, @hpxml.pv_systems, utility_bill_scenario)
992
+ @expected_bills['Test: Electricity: Fixed (USD)'] = 200
993
+ @expected_bills['Test: Electricity: Energy (USD)'] = 632
994
+ @expected_bills['Test: Electricity: PV Credit (USD)'] = -1777
995
+ expected_bills = _get_expected_bills(@expected_bills)
996
+ _check_bills(expected_bills, actual_bills)
997
+ end
998
+ end
999
+
1000
+ def test_downloaded_utility_rates
1001
+ require 'rubygems/package'
1002
+ require 'zip'
1003
+ require 'tempfile'
1004
+
1005
+ @hpxml.header.utility_bill_scenarios.each do |utility_bill_scenario|
1006
+ Zip.on_exists_proc = true
1007
+ Zip::File.open(File.join(File.dirname(__FILE__), '../resources/detailed_rates/openei_rates.zip')) do |zip_file|
1008
+ zip_file.each do |entry|
1009
+ next unless entry.file?
1010
+
1011
+ tmpdir = Dir.tmpdir
1012
+ tmpfile = Tempfile.new(['rate', '.json'], tmpdir)
1013
+ tmp_path = tmpfile.path.to_s
1014
+
1015
+ File.open(tmp_path, 'wb') do |f|
1016
+ f.print entry.get_input_stream.read
1017
+
1018
+ utility_bill_scenario.elec_tariff_filepath = tmp_path
1019
+ File.delete(@bills_csv) if File.exist? @bills_csv
1020
+ actual_bills = _bill_calcs(@fuels_pv_none_detailed, @hpxml.header, [], utility_bill_scenario)
1021
+ if !File.exist?(@bills_csv)
1022
+ puts entry.name
1023
+ assert(false)
1024
+ end
1025
+ if entry.name.include? 'North Slope Borough Power Light - Aged or Handicappedseniors over 60'
1026
+ # No cost if < 600 kWh/month, which is the case for PV_None.csv
1027
+ assert_nil(actual_bills['Test: Electricity: Total (USD)'])
1028
+ else
1029
+ assert_operator(actual_bills['Test: Electricity: Total (USD)'], :>, 0)
1030
+ end
1031
+ end
1032
+ end
1033
+ end
1034
+ end
1035
+ end
1036
+
1037
+ def _get_expected_bills(expected_bills)
1038
+ expected_bills['Test: Electricity: Total (USD)'] = expected_bills['Test: Electricity: Fixed (USD)'] + expected_bills['Test: Electricity: Energy (USD)'] + expected_bills['Test: Electricity: PV Credit (USD)']
1039
+ expected_bills['Test: Natural Gas: Total (USD)'] = expected_bills['Test: Natural Gas: Fixed (USD)'] + expected_bills['Test: Natural Gas: Energy (USD)']
1040
+ expected_bills['Test: Fuel Oil: Total (USD)'] = expected_bills['Test: Fuel Oil: Fixed (USD)'] + expected_bills['Test: Fuel Oil: Energy (USD)']
1041
+ expected_bills['Test: Propane: Total (USD)'] = expected_bills['Test: Propane: Fixed (USD)'] + expected_bills['Test: Propane: Energy (USD)']
1042
+ expected_bills['Test: Coal: Total (USD)'] = expected_bills['Test: Coal: Fixed (USD)'] + expected_bills['Test: Coal: Energy (USD)']
1043
+ expected_bills['Test: Wood Cord: Total (USD)'] = expected_bills['Test: Wood Cord: Fixed (USD)'] + expected_bills['Test: Wood Cord: Energy (USD)']
1044
+ expected_bills['Test: Wood Pellets: Total (USD)'] = expected_bills['Test: Wood Pellets: Fixed (USD)'] + expected_bills['Test: Wood Pellets: Energy (USD)']
1045
+ expected_bills['Test: Total (USD)'] = expected_bills['Test: Electricity: Total (USD)'] + expected_bills['Test: Natural Gas: Total (USD)'] + expected_bills['Test: Fuel Oil: Total (USD)'] + expected_bills['Test: Propane: Total (USD)'] + expected_bills['Test: Wood Cord: Total (USD)'] + expected_bills['Test: Wood Pellets: Total (USD)'] + expected_bills['Test: Coal: Total (USD)']
1046
+ return expected_bills
1047
+ end
1048
+
1049
+ def _check_bills(expected_bills, actual_bills)
1050
+ bills = expected_bills.keys | actual_bills.keys
1051
+ bills.each do |bill|
1052
+ assert(expected_bills.keys.include?(bill))
1053
+ if expected_bills[bill] != 0
1054
+ assert(actual_bills.keys.include?(bill))
1055
+ assert_in_delta(expected_bills[bill], actual_bills[bill], 1) # within a dollar
1056
+ end
1057
+ end
1058
+ end
1059
+
1060
+ def _load_timeseries(pv_size_kw, use_hourly_electricity)
1061
+ fuels = @measure.setup_fuel_outputs()
1062
+ columns = CSV.read(File.join(File.dirname(__FILE__), 'data.csv')).transpose
330
1063
  columns.each do |col|
331
1064
  col_name = col[0]
332
1065
  next if col_name == 'Date/Time'
333
1066
 
334
1067
  values = col[1..-1].map { |v| Float(v) }
335
1068
 
336
- if col_name == 'ELECTRICITY:UNIT_1 [J](Hourly)'
337
- fuel = fuels[[FT::Elec, false]]
338
- unit_conv = UnitConversions.convert(1.0, 'J', fuel.units)
339
- fuel.timeseries = values.map { |v| v * unit_conv }
340
- elsif col_name == 'GAS:UNIT_1 [J](Hourly)'
341
- fuel = fuels[[FT::Gas, false]]
342
- unit_conv = UnitConversions.convert(1.0, 'J', fuel.units)
343
- fuel.timeseries = values.map { |v| v * unit_conv }
344
- elsif col_name == 'Appl_1:ExteriorEquipment:Propane [J](Hourly)'
345
- fuel = fuels[[FT::Propane, false]]
346
- unit_conv = UnitConversions.convert(1.0, 'J', fuel.units) / 91.6
347
- fuel.timeseries = values.map { |v| v * unit_conv }
348
- elsif col_name == 'FUELOIL:UNIT_1 [m3](Hourly)'
349
- fuel = fuels[[FT::Oil, false]]
350
- unit_conv = UnitConversions.convert(1.0, 'm^3', 'gal')
351
- fuel.timeseries = values.map { |v| v * unit_conv }
352
- elsif col_name == 'PV:ELECTRICITY_1 [J](Hourly) '
353
- fuel = fuels[[FT::Elec, true]]
354
- unit_conv = UnitConversions.convert(1.0, 'J', fuel.units)
355
- fuel.timeseries = values.map { |v| v * unit_conv }
1069
+ if col_name == 'Electricity [kWh]'
1070
+ fuels[[FT::Elec, false]].timeseries = values
1071
+ elsif col_name == 'Gas [therm]'
1072
+ fuels[[FT::Gas, false]].timeseries = values
1073
+ elsif col_name == 'Propane [gal]'
1074
+ fuels[[FT::Propane, false]].timeseries = values
1075
+ elsif col_name == 'Oil [gal]'
1076
+ fuels[[FT::Oil, false]].timeseries = values
1077
+ elsif col_name == "PV_#{pv_size_kw}kW [kWh]"
1078
+ fuels[[FT::Elec, true]].timeseries = values
356
1079
  end
357
1080
  end
358
1081
 
359
- fuels.each do |(fuel_type, is_production), fuel|
1082
+ fuels.values.each do |fuel|
360
1083
  fuel.timeseries = [0] * fuels[[FT::Elec, false]].timeseries.size if fuel.timeseries.empty?
361
1084
  end
362
1085
 
363
- # Convert hourly data to monthly data
1086
+ # Convert hourly data to monthly data as appropriate
364
1087
  num_days_in_month = Constants.NumDaysInMonths(2002) # Arbitrary non-leap year
365
- fuels.each do |(fuel_type, is_production), fuel|
1088
+ fuels.each do |(fuel_type, _is_production), fuel|
1089
+ next unless fuel_type != FT::Elec || (fuel_type == FT::Elec && !use_hourly_electricity)
1090
+
366
1091
  ts_data = fuel.timeseries.dup
367
1092
  fuel.timeseries = []
368
1093
  start_day = 0
@@ -371,28 +1096,31 @@ class ReportUtilityBillsTest < MiniTest::Test
371
1096
  start_day += num_days
372
1097
  end
373
1098
  end
1099
+
1100
+ return fuels
374
1101
  end
375
1102
 
376
- def _bill_calcs(fuels, utility_rates, utility_bills, header, pv_systems)
377
- args = Hash[@args_hash.collect { |k, v| [k.to_sym, v] }]
378
- args[:electricity_bill_type] = 'Simple'
1103
+ def _bill_calcs(fuels, header, pv_systems, utility_bill_scenario)
379
1104
  runner = OpenStudio::Measure::OSRunner.new(OpenStudio::WorkflowJSON.new)
380
1105
  output_format = 'csv'
381
1106
  output_path = File.join(File.dirname(__FILE__), "results_bills.#{output_format}")
382
1107
 
383
- @measure.get_utility_rates(fuels, utility_rates, args, header.state_code, pv_systems)
384
- net_elec = @measure.get_utility_bills(fuels, utility_rates, utility_bills, args, header)
385
- @measure.annual_true_up(utility_rates, utility_bills, net_elec)
386
- @measure.get_annual_bills(utility_bills)
1108
+ utility_rates, utility_bills = @measure.setup_utility_outputs()
1109
+ @measure.get_utility_rates(@hpxml_path, fuels, utility_rates, utility_bill_scenario, pv_systems)
1110
+ @measure.get_utility_bills(fuels, utility_rates, utility_bills, utility_bill_scenario, header)
1111
+
1112
+ @measure.report_runperiod_output_results(runner, utility_bills, output_format, output_path, utility_bill_scenario.name)
387
1113
 
388
- @measure.write_output(runner, utility_bills, output_format, output_path)
1114
+ # Check written values exist and are registered
1115
+ assert(File.exist?(@bills_csv))
1116
+ actual_bills = _get_actual_bills(@bills_csv)
389
1117
 
390
- bills_csv = File.join(File.dirname(__FILE__), 'results_bills.csv')
1118
+ _check_for_runner_registered_values(runner, nil, actual_bills)
391
1119
 
392
- return bills_csv
1120
+ return actual_bills
393
1121
  end
394
1122
 
395
- def _test_measure(expected_errors: [], expected_warnings: [])
1123
+ def _test_measure(hpxml: nil, expected_errors: [], expected_warnings: [])
396
1124
  # Run measure via OSW
397
1125
  require 'json'
398
1126
  template_osw = File.join(File.dirname(__FILE__), '..', '..', 'workflow', 'template-run-hpxml.osw')
@@ -428,7 +1156,7 @@ class ReportUtilityBillsTest < MiniTest::Test
428
1156
 
429
1157
  bills_csv = File.join(File.dirname(template_osw), 'run', 'results_bills.csv')
430
1158
 
431
- # check warnings/errors
1159
+ # Check warnings/errors
432
1160
  if not expected_errors.empty?
433
1161
  expected_errors.each do |expected_error|
434
1162
  assert(cli_output.include?("ERROR] #{expected_error}"))
@@ -440,6 +1168,49 @@ class ReportUtilityBillsTest < MiniTest::Test
440
1168
  end
441
1169
  end
442
1170
 
443
- return bills_csv
1171
+ if !hpxml.nil?
1172
+ return if hpxml.header.utility_bill_scenarios.empty?
1173
+ elsif (not expected_errors.empty?) || (not expected_warnings.empty?)
1174
+ return
1175
+ end
1176
+
1177
+ # Check written values exist and are registered
1178
+ assert(File.exist?(bills_csv))
1179
+ actual_bills = _get_actual_bills(bills_csv)
1180
+
1181
+ _check_for_runner_registered_values(nil, File.join(File.dirname(bills_csv), 'results.json'), actual_bills)
1182
+
1183
+ return actual_bills
1184
+ end
1185
+
1186
+ def _get_actual_bills(bills_csv)
1187
+ actual_bills = {}
1188
+ File.readlines(bills_csv).each do |line|
1189
+ next if line.strip.empty?
1190
+
1191
+ key, value = line.split(',').map { |x| x.strip }
1192
+ actual_bills[key] = Float(value)
1193
+ end
1194
+ return actual_bills
1195
+ end
1196
+
1197
+ def _check_for_runner_registered_values(runner, results_json, actual_bills)
1198
+ if !runner.nil?
1199
+ runner_bills = {}
1200
+ runner.result.stepValues.each do |step_value|
1201
+ runner_bills[step_value.name] = get_value_from_workflow_step_value(step_value)
1202
+ end
1203
+ elsif !results_json.nil?
1204
+ require 'json'
1205
+ runner_bills = JSON.parse(File.read(results_json))
1206
+ runner_bills = runner_bills['ReportUtilityBills']
1207
+ end
1208
+
1209
+ actual_bills.each do |name, value|
1210
+ name = OpenStudio::toUnderscoreCase(name).chomp('_')
1211
+
1212
+ assert_includes(runner_bills.keys, name)
1213
+ assert_equal(value, runner_bills[name])
1214
+ end
444
1215
  end
445
1216
  end