urbanopt-cli 0.8.3 → 0.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (657) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -6
  3. data/CHANGELOG.md +20 -0
  4. data/CMakeLists.txt +7 -7
  5. data/Gemfile +3 -1
  6. data/LICENSE.md +1 -1
  7. data/README.md +9 -0
  8. data/Rakefile +1 -1
  9. data/example_files/Gemfile +23 -16
  10. data/example_files/Gemfile.lock +177 -0
  11. data/example_files/base_workflow_res.osw +57 -14
  12. data/example_files/class_project_coincident.json +1322 -0
  13. data/example_files/class_project_diverse.json +1322 -0
  14. data/example_files/disco/config.json +42 -0
  15. data/example_files/disco/cost_database.xlsx +0 -0
  16. data/example_files/disco/technical_catalog.json +12126 -0
  17. data/example_files/mappers/Baseline.rb +11 -8
  18. data/example_files/mappers/ChilledWaterStorage.rb +98 -0
  19. data/example_files/mappers/ClassProject.rb +110 -0
  20. data/example_files/mappers/CreateBar.rb +2 -1
  21. data/example_files/mappers/EvCharging.rb +1 -1
  22. data/example_files/mappers/FlexibleHotWater.rb +1 -1
  23. data/example_files/mappers/Floorspace.rb +1 -1
  24. data/example_files/mappers/HighEfficiency.rb +14 -12
  25. data/example_files/mappers/HighEfficiencyCreateBar.rb +1 -1
  26. data/example_files/mappers/HighEfficiencyFloorspace.rb +1 -1
  27. data/example_files/mappers/PeakHoursMelsShedding.rb +72 -0
  28. data/example_files/mappers/PeakHoursThermostatAdjust.rb +78 -0
  29. data/example_files/mappers/ThermalStorage.rb +2 -1
  30. data/example_files/mappers/base_workflow.osw +55 -14
  31. data/example_files/mappers/class_project_workflow.osw +328 -0
  32. data/example_files/mappers/createbar_workflow.osw +16 -16
  33. data/example_files/measures/BuildResidentialModel/measure.rb +7 -1
  34. data/example_files/measures/BuildResidentialModel/measure.xml +1313 -706
  35. data/example_files/opendss/electrical_database.json +1446 -1446
  36. data/example_files/python_deps/dependencies.json +5 -0
  37. data/example_files/python_deps/install_python.ps1 +96 -0
  38. data/example_files/python_deps/install_python.sh +120 -0
  39. data/example_files/residential/clothes_dryer.tsv +11 -11
  40. data/example_files/residential/clothes_washer.tsv +3 -3
  41. data/example_files/residential/dishwasher.tsv +3 -3
  42. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +0 -1
  43. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +8 -21
  44. data/example_files/resources/hpxml-measures/.gitignore +2 -0
  45. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +1272 -1094
  46. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +978 -659
  47. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +52 -74
  48. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +77 -140
  49. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.rb +37 -27
  50. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml +42 -15
  51. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb +70 -51
  52. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/tests/build_residential_schedule_file_test.rb +142 -21
  53. data/example_files/resources/hpxml-measures/Changelog.md +95 -19
  54. data/example_files/resources/hpxml-measures/Gemfile +2 -4
  55. data/example_files/resources/hpxml-measures/Gemfile.lock +2 -13
  56. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +276 -300
  57. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +220 -214
  58. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +215 -170
  59. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/battery.rb +115 -18
  60. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +24 -44
  61. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +564 -197
  62. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/cambium/README.md +8 -8
  63. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +1 -0
  64. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +7 -55
  65. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +24 -19
  66. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +541 -211
  67. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +305 -176
  68. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXML.xsd +0 -2
  69. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLBaseElements.xsd +230 -141
  70. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLDataTypes.xsd +145 -137
  71. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml +191 -97
  72. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/iso-schematron.xsd +391 -0
  73. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +194 -198
  74. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +140 -145
  75. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +11 -11
  76. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +33 -1
  77. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb +4 -4
  78. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +17 -9
  79. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +14 -12
  80. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/output.rb +39 -17
  81. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/psychrometrics.rb +1 -1
  82. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/battery.csv +8761 -0
  83. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +114 -57
  84. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +1 -0
  85. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb +148 -0
  86. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +2 -2
  87. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +90 -128
  88. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/weather.rb +26 -32
  89. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +2 -14
  90. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlvalidator.rb +67 -0
  91. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +117 -56
  92. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_battery.rb +141 -14
  93. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +471 -344
  94. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +124 -20
  95. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +1 -1
  96. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +28 -32
  97. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +172 -79
  98. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +54 -8
  99. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +3 -3
  100. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +4 -4
  101. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +7 -7
  102. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +1 -1
  103. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_schedules.rb +6 -9
  104. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +8 -8
  105. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +213 -95
  106. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +1 -10
  107. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_weather.rb +76 -0
  108. data/example_files/resources/hpxml-measures/README.md +2 -3
  109. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.rb +587 -284
  110. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.xml +304 -352
  111. data/example_files/resources/hpxml-measures/ReportSimulationOutput/tests/output_report_test.rb +404 -279
  112. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.rb +222 -501
  113. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.xml +137 -200
  114. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Annual Charge.json +649 -0
  115. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Monthly Charge.json +649 -0
  116. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json +647 -0
  117. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate Min Annual Charge.json +8776 -0
  118. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate Min Monthly Charge.json +8776 -0
  119. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json +8774 -0
  120. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate Min Annual Charge.json +659 -0
  121. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate Min Monthly Charge.json +659 -0
  122. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json +657 -0
  123. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate Min Annual Charge.json +670 -0
  124. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate Min Monthly Charge.json +670 -0
  125. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json +668 -0
  126. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate Min Annual Charge.json +655 -0
  127. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate Min Monthly Charge.json +655 -0
  128. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json +653 -0
  129. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/openei_rates.zip +0 -0
  130. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/Average_retail_price_of_electricity.csv +0 -0
  131. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/HouseholdConsumption.csv +0 -0
  132. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/NG_PRI_SUM_A_EPG0_PRS_DMCF_A.csv +0 -0
  133. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/PET_PRI_WFR_A_EPD2F_PRS_DPGAL_W.csv +0 -0
  134. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/PET_PRI_WFR_A_EPLLPA_PRS_DPGAL_W.csv +0 -0
  135. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/README.md +0 -0
  136. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/util.rb +506 -25
  137. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Contains Demand Charges.json +1312 -0
  138. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Invalid Fixed Charge Units.json +657 -0
  139. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Invalid Min Charge Units.json +659 -0
  140. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/JacksonElectricMemberCorp-ResidentialSeniorCitizenLowIncomeAssistance.json +681 -0
  141. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/Missing Required Fields.json +54 -0
  142. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/data.csv +8761 -0
  143. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/utility_bills_test.rb +1006 -235
  144. data/example_files/resources/hpxml-measures/docs/source/conf.py +1 -1
  145. data/example_files/resources/hpxml-measures/docs/source/intro.rst +0 -1
  146. data/example_files/resources/hpxml-measures/docs/source/usage_instructions.rst +4 -3
  147. data/example_files/resources/hpxml-measures/docs/source/workflow_inputs.rst +468 -264
  148. data/example_files/resources/hpxml-measures/docs/source/workflow_outputs.rst +148 -154
  149. data/example_files/resources/hpxml-measures/tasks.rb +616 -802
  150. data/example_files/resources/hpxml-measures/workflow/real_homes/house001.xml +19 -11
  151. data/example_files/resources/hpxml-measures/workflow/real_homes/house002.xml +20 -12
  152. data/example_files/resources/hpxml-measures/workflow/real_homes/house003.xml +12 -7
  153. data/example_files/resources/hpxml-measures/workflow/real_homes/house004.xml +12 -7
  154. data/example_files/resources/hpxml-measures/workflow/real_homes/house005.xml +19 -11
  155. data/example_files/resources/hpxml-measures/workflow/real_homes/house006.xml +12 -7
  156. data/example_files/resources/hpxml-measures/workflow/real_homes/house007.xml +20 -12
  157. data/example_files/resources/hpxml-measures/workflow/real_homes/house008.xml +28 -16
  158. data/example_files/resources/hpxml-measures/workflow/real_homes/house009.xml +28 -17
  159. data/example_files/resources/hpxml-measures/workflow/real_homes/house010.xml +28 -16
  160. data/example_files/resources/hpxml-measures/workflow/real_homes/house011.xml +20 -12
  161. data/example_files/resources/hpxml-measures/workflow/real_homes/house012.xml +20 -12
  162. data/example_files/resources/hpxml-measures/workflow/real_homes/house013.xml +20 -12
  163. data/example_files/resources/hpxml-measures/workflow/real_homes/house014.xml +20 -12
  164. data/example_files/resources/hpxml-measures/workflow/real_homes/house015.xml +20 -12
  165. data/example_files/resources/hpxml-measures/workflow/real_homes/house016.xml +22 -12
  166. data/example_files/resources/hpxml-measures/workflow/real_homes/house017.xml +19 -11
  167. data/example_files/resources/hpxml-measures/workflow/real_homes/house018.xml +20 -12
  168. data/example_files/resources/hpxml-measures/workflow/real_homes/house019.xml +13 -7
  169. data/example_files/resources/hpxml-measures/workflow/real_homes/house020.xml +12 -7
  170. data/example_files/resources/hpxml-measures/workflow/real_homes/house021.xml +31 -16
  171. data/example_files/resources/hpxml-measures/workflow/real_homes/house022.xml +22 -12
  172. data/example_files/resources/hpxml-measures/workflow/real_homes/house023.xml +21 -12
  173. data/example_files/resources/hpxml-measures/workflow/real_homes/house024.xml +37 -22
  174. data/example_files/resources/hpxml-measures/workflow/real_homes/house025.xml +24 -12
  175. data/example_files/resources/hpxml-measures/workflow/real_homes/house026.xml +33 -21
  176. data/example_files/resources/hpxml-measures/workflow/real_homes/house027.xml +28 -16
  177. data/example_files/resources/hpxml-measures/workflow/real_homes/house028.xml +28 -16
  178. data/example_files/resources/hpxml-measures/workflow/real_homes/house029.xml +30 -17
  179. data/example_files/resources/hpxml-measures/workflow/real_homes/house030.xml +10 -7
  180. data/example_files/resources/hpxml-measures/workflow/real_homes/house031.xml +22 -11
  181. data/example_files/resources/hpxml-measures/workflow/real_homes/house032.xml +12 -7
  182. data/example_files/resources/hpxml-measures/workflow/real_homes/house033.xml +18 -12
  183. data/example_files/resources/hpxml-measures/workflow/real_homes/house034.xml +25 -16
  184. data/example_files/resources/hpxml-measures/workflow/real_homes/house035.xml +22 -12
  185. data/example_files/resources/hpxml-measures/workflow/real_homes/house036.xml +20 -12
  186. data/example_files/resources/hpxml-measures/workflow/real_homes/house037.xml +26 -17
  187. data/example_files/resources/hpxml-measures/workflow/real_homes/house038.xml +19 -11
  188. data/example_files/resources/hpxml-measures/workflow/real_homes/house039.xml +25 -16
  189. data/example_files/resources/hpxml-measures/workflow/real_homes/house040.xml +20 -12
  190. data/example_files/resources/hpxml-measures/workflow/real_homes/house041.xml +35 -21
  191. data/example_files/resources/hpxml-measures/workflow/real_homes/house042.xml +28 -17
  192. data/example_files/resources/hpxml-measures/workflow/real_homes/house043.xml +20 -12
  193. data/example_files/resources/hpxml-measures/workflow/real_homes/house044.xml +35 -21
  194. data/example_files/resources/hpxml-measures/workflow/real_homes/house045.xml +20 -12
  195. data/example_files/resources/hpxml-measures/workflow/real_homes/house046.xml +20 -13
  196. data/example_files/resources/hpxml-measures/workflow/real_homes/house047.xml +12 -9
  197. data/example_files/resources/hpxml-measures/workflow/real_homes/house048.xml +25 -14
  198. data/example_files/resources/hpxml-measures/workflow/real_homes/house049.xml +10 -7
  199. data/example_files/resources/hpxml-measures/workflow/real_homes/house050.xml +20 -11
  200. data/example_files/resources/hpxml-measures/workflow/run_simulation.rb +91 -88
  201. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-coal.xml +18 -7
  202. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-portable.xml +546 -535
  203. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-ief-whole-home.xml +546 -535
  204. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier-multiple.xml +555 -544
  205. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-dehumidifier.xml +18 -7
  206. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-gas.xml +18 -7
  207. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-modified.xml +18 -7
  208. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-none.xml +18 -7
  209. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil-location-miami-fl.xml +580 -569
  210. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-oil.xml +18 -7
  211. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane-location-portland-or.xml +580 -569
  212. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-propane.xml +18 -7
  213. data/example_files/resources/hpxml-measures/workflow/sample_files/base-appliances-wood.xml +18 -7
  214. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-cathedral.xml +7 -0
  215. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-conditioned.xml +17 -6
  216. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-flat.xml +7 -0
  217. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-radiant-barrier.xml +18 -7
  218. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-unvented-insulated-roof.xml +18 -7
  219. data/example_files/resources/hpxml-measures/workflow/sample_files/base-atticroof-vented.xml +18 -7
  220. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery-scheduled.xml +600 -0
  221. data/example_files/resources/hpxml-measures/workflow/sample_files/base-battery.xml +598 -587
  222. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multifamily-buffer-space.xml +494 -485
  223. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-multiple.xml +606 -593
  224. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-non-freezing-space.xml +494 -485
  225. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-heated-space.xml +494 -485
  226. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-adjacent-to-other-housing-unit.xml +494 -485
  227. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-calctype-operational.xml +480 -471
  228. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-baseboard.xml +464 -457
  229. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil-ducted.xml +496 -487
  230. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-fan-coil.xml +466 -459
  231. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-chiller-water-loop-heat-pump.xml +518 -509
  232. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-cooling-tower-water-loop-heat-pump.xml +513 -504
  233. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-baseboard.xml +445 -438
  234. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-ducted.xml +476 -467
  235. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil-eae.xml +443 -436
  236. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-fan-coil.xml +446 -439
  237. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-boiler-only-water-loop-heat-pump.xml +494 -485
  238. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-baseboard.xml +445 -438
  239. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil-ducted.xml +476 -467
  240. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-fan-coil.xml +446 -439
  241. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-chiller-only-water-loop-heat-pump.xml +494 -485
  242. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-cooling-tower-only-water-loop-heat-pump.xml +489 -480
  243. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-generator.xml +499 -490
  244. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-ground-loop-ground-to-air-heat-pump.xml +491 -482
  245. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room-multiple-water-heaters.xml +510 -0
  246. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-laundry-room.xml +495 -486
  247. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-multiple.xml +709 -695
  248. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent-preconditioning.xml +528 -519
  249. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-mechvent.xml +512 -503
  250. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-pv.xml +504 -495
  251. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater-recirc.xml +497 -488
  252. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily-shared-water-heater.xml +490 -481
  253. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-multifamily.xml +487 -478
  254. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached-2stories.xml +639 -628
  255. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached-atticroof-cathedral.xml +587 -580
  256. data/example_files/resources/hpxml-measures/workflow/sample_files/base-bldgtype-single-family-attached.xml +639 -628
  257. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-defaults.xml +539 -528
  258. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-loads-large-uncommon.xml +644 -633
  259. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational-misc-loads-large-uncommon2.xml +644 -633
  260. data/example_files/resources/hpxml-measures/workflow/sample_files/base-calctype-operational.xml +575 -564
  261. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless-outside.xml +16 -7
  262. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-combi-tankless.xml +16 -7
  263. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-2-speed.xml +18 -7
  264. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-gshp.xml +585 -574
  265. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-hpwh.xml +18 -7
  266. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-tankless.xml +18 -7
  267. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater-var-speed.xml +18 -7
  268. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-desuperheater.xml +18 -7
  269. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-dwhr.xml +18 -7
  270. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-detailed-setpoints.xml +536 -0
  271. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-dse.xml +16 -7
  272. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-outside.xml +16 -7
  273. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-standbyloss.xml +20 -8
  274. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect-with-solar-fraction.xml +16 -7
  275. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-indirect.xml +16 -7
  276. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-electric.xml +18 -7
  277. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-gas.xml +18 -7
  278. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-hpwh.xml +18 -7
  279. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-jacket-indirect.xml +16 -7
  280. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-low-flow-fixtures.xml +18 -7
  281. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-multiple.xml +16 -7
  282. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-none.xml +18 -7
  283. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-demand.xml +19 -8
  284. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-manual.xml +19 -8
  285. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-nocontrol.xml +19 -8
  286. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-temperature.xml +19 -8
  287. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-recirc-timer.xml +19 -8
  288. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-evacuated-tube.xml +18 -7
  289. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-flat-plate.xml +18 -7
  290. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-direct-ics.xml +18 -7
  291. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-fraction.xml +18 -7
  292. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-indirect-flat-plate.xml +18 -7
  293. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-solar-thermosyphon-flat-plate.xml +18 -7
  294. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-coal.xml +18 -7
  295. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-detailed-setpoints.xml +582 -571
  296. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-elec-uef.xml +583 -572
  297. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-outside.xml +18 -7
  298. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef-fhr.xml +584 -573
  299. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas-uef.xml +584 -573
  300. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-gas.xml +18 -7
  301. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-detailed-schedules.xml +583 -572
  302. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-operating-mode-heat-pump-only.xml +585 -574
  303. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-outside.xml +18 -7
  304. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-uef.xml +582 -571
  305. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar-fraction.xml +18 -7
  306. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump-with-solar.xml +18 -7
  307. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-heat-pump.xml +18 -7
  308. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified-detailed-occupancy-stochastic.xml +586 -575
  309. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-model-type-stratified.xml +585 -574
  310. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-oil.xml +18 -7
  311. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tank-wood.xml +18 -7
  312. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-detailed-setpoints.xml +580 -569
  313. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-outside.xml +18 -7
  314. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric-uef.xml +580 -569
  315. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-electric.xml +18 -7
  316. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-uef.xml +580 -569
  317. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar-fraction.xml +18 -7
  318. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas-with-solar.xml +18 -7
  319. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-gas.xml +18 -7
  320. data/example_files/resources/hpxml-measures/workflow/sample_files/base-dhw-tankless-propane.xml +18 -7
  321. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories-garage.xml +28 -11
  322. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-2stories.xml +20 -7
  323. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-1.xml +18 -7
  324. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-2.xml +18 -7
  325. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-4.xml +18 -7
  326. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-beds-5.xml +18 -7
  327. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-ceilingtypes.xml +607 -0
  328. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-floortypes.xml +550 -0
  329. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-garage.xml +27 -12
  330. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-ach-house-pressure.xml +18 -7
  331. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm-house-pressure.xml +18 -7
  332. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-cfm50.xml +18 -7
  333. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-flue.xml +18 -7
  334. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-infil-natural-ach.xml +18 -7
  335. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-orientations.xml +589 -578
  336. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-overhangs.xml +18 -7
  337. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-rooftypes.xml +18 -7
  338. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-physical-properties.xml +619 -608
  339. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-shading.xml +620 -609
  340. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights-storms.xml +618 -607
  341. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-skylights.xml +18 -7
  342. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-level.xml +537 -526
  343. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces.xml +90 -43
  344. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-split-surfaces2.xml +2507 -2460
  345. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-thermal-mass.xml +595 -584
  346. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-walltypes.xml +19 -8
  347. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-natural-ventilation-availability.xml +584 -0
  348. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-none.xml +18 -7
  349. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-physical-properties.xml +594 -583
  350. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-shading.xml +597 -586
  351. data/example_files/resources/hpxml-measures/workflow/sample_files/base-enclosure-windows-storms.xml +598 -587
  352. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-ambient.xml +27 -12
  353. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-basement-garage.xml +671 -656
  354. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-complex.xml +18 -7
  355. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-basement-slab-insulation.xml +18 -7
  356. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-foundation-conditioned-basement-wall-interior-insulation.xml → base-foundation-conditioned-basement-wall-insulation.xml} +585 -574
  357. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-conditioned-crawlspace.xml +582 -571
  358. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-multiple.xml +35 -16
  359. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-slab.xml +18 -7
  360. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-above-grade.xml +27 -12
  361. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-assembly-r.xml +27 -12
  362. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement-wall-insulation.xml +27 -12
  363. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unconditioned-basement.xml +27 -12
  364. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-unvented-crawlspace.xml +27 -12
  365. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-vented-crawlspace.xml +27 -12
  366. data/example_files/resources/hpxml-measures/workflow/sample_files/base-foundation-walkout-basement.xml +18 -7
  367. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-backup-lockout-temperature.xml +586 -575
  368. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-cooling-only.xml +573 -562
  369. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-heating-only.xml +580 -569
  370. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed-seer2-hspf2.xml +583 -0
  371. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-1-speed.xml +18 -7
  372. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-2-speed.xml +18 -7
  373. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler-switchover-temperature.xml +600 -589
  374. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-boiler.xml +599 -588
  375. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed-backup-furnace.xml +629 -616
  376. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-air-to-air-heat-pump-var-speed.xml +18 -7
  377. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-cooling-only.xml +573 -562
  378. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-heating-only.xml +579 -568
  379. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +581 -570
  380. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +581 -570
  381. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload-miami-fl.xml +582 -0
  382. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +581 -570
  383. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-acca.xml +581 -570
  384. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-hers.xml +581 -570
  385. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-2-speed-sizing-methodology-maxload.xml +581 -570
  386. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-boiler.xml +598 -587
  387. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-backup-furnace.xml +628 -615
  388. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-acca.xml +581 -570
  389. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-hers.xml +581 -570
  390. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-air-to-air-heat-pump-var-speed-sizing-methodology-maxload.xml +581 -570
  391. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-elec-only.xml +535 -526
  392. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-central-ac-1-speed.xml +589 -578
  393. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-boiler-gas-only.xml +536 -527
  394. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-1-speed.xml +18 -7
  395. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-2-speed.xml +565 -554
  396. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-only-var-speed.xml +565 -554
  397. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-central-ac-plus-air-to-air-heat-pump-heating.xml +18 -7
  398. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-acca.xml +582 -571
  399. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-hers.xml +582 -571
  400. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-air-to-air-heat-pump-1-speed-sizing-methodology-maxload.xml +582 -571
  401. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-dual-fuel-mini-split-heat-pump-ducted.xml +18 -7
  402. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-elec-resistance-only.xml +526 -517
  403. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-evap-cooler-furnace-gas.xml +573 -562
  404. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-floor-furnace-propane-only.xml +529 -520
  405. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-elec-only.xml +565 -554
  406. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-2-speed.xml +580 -569
  407. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-central-ac-var-speed.xml +580 -569
  408. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-only.xml +565 -554
  409. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-furnace-gas-room-ac.xml +578 -567
  410. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-cooling-only.xml +575 -564
  411. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-heating-only.xml +581 -570
  412. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-acca.xml +583 -572
  413. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-hers.xml +583 -572
  414. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ground-to-air-heat-pump-sizing-methodology-maxload.xml +583 -572
  415. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-air-conditioner-only-ducted.xml +18 -7
  416. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-cooling-only.xml +18 -7
  417. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-heating-only.xml +18 -7
  418. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-acca.xml +580 -569
  419. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-hers.xml +580 -569
  420. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ducted-sizing-methodology-maxload.xml +580 -569
  421. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-mini-split-heat-pump-ductless-backup-stove.xml +551 -542
  422. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac-with-heating.xml +532 -530
  423. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-ptac.xml +525 -516
  424. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-acca.xml +541 -532
  425. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-hers.xml +541 -532
  426. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-pthp-sizing-methodology-maxload.xml +541 -532
  427. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-only.xml +525 -516
  428. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-heating.xml +533 -0
  429. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-acca.xml +542 -0
  430. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-hers.xml +542 -0
  431. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-room-ac-with-reverse-cycle-sizing-methodology-maxload.xml +542 -0
  432. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-stove-oil-only.xml +529 -520
  433. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize-wall-furnace-elec-only.xml +529 -520
  434. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-autosize.xml +580 -569
  435. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-coal-only.xml +16 -7
  436. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-elec-only.xml +16 -7
  437. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-central-ac-1-speed.xml +18 -7
  438. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-gas-only.xml +16 -7
  439. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-oil-only.xml +16 -7
  440. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-propane-only.xml +16 -7
  441. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-boiler-wood-only.xml +16 -7
  442. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed-seer2.xml +567 -0
  443. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-1-speed.xml +18 -7
  444. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-2-speed.xml +18 -7
  445. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-only-var-speed.xml +18 -7
  446. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-central-ac-plus-air-to-air-heat-pump-heating.xml +18 -7
  447. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dse.xml +16 -7
  448. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed-electric.xml +18 -7
  449. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-1-speed.xml +18 -7
  450. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-2-speed.xml +18 -7
  451. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-air-to-air-heat-pump-var-speed.xml +18 -7
  452. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-dual-fuel-mini-split-heat-pump-ducted.xml +18 -7
  453. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-fractions.xml +611 -598
  454. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-area-multipliers.xml +589 -0
  455. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-cfm50.xml +582 -571
  456. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ducts-leakage-percent.xml +18 -7
  457. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-elec-resistance-only.xml +16 -7
  458. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-furnace-gas.xml +18 -7
  459. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only-ducted.xml +17 -7
  460. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-evap-cooler-only.xml +16 -7
  461. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fireplace-wood-only.xml +530 -521
  462. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-fixed-heater-gas-only.xml +530 -521
  463. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-floor-furnace-propane-only.xml +530 -521
  464. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-coal-only.xml +566 -555
  465. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-central-ac-1-speed.xml +18 -7
  466. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-elec-only.xml +18 -7
  467. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-2-speed.xml +18 -7
  468. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-central-ac-var-speed.xml +18 -7
  469. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only-detailed-setpoints.xml +566 -555
  470. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-only.xml +566 -555
  471. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-gas-room-ac.xml +18 -7
  472. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-oil-only.xml +18 -7
  473. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-propane-only.xml +18 -7
  474. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-wood-only.xml +18 -7
  475. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-furnace-x3-dse.xml +16 -7
  476. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-cooling-only.xml +574 -563
  477. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump-heating-only.xml +581 -570
  478. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ground-to-air-heat-pump.xml +583 -572
  479. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-1-speed.xml +587 -576
  480. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-2-speed.xml +587 -576
  481. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-air-to-air-heat-pump-var-speed.xml +587 -576
  482. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-1-speed.xml +591 -580
  483. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-2-speed.xml +591 -580
  484. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-central-ac-var-speed.xml +591 -580
  485. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-furnace-gas-only.xml +570 -559
  486. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-ground-to-air-heat-pump.xml +586 -575
  487. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-air-conditioner-only-ducted.xml +570 -559
  488. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-install-quality-mini-split-heat-pump-ducted.xml +586 -575
  489. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ducted.xml +18 -7
  490. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-air-conditioner-only-ductless.xml +16 -7
  491. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-cooling-only.xml +18 -7
  492. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted-heating-only.xml +18 -7
  493. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ducted.xml +18 -7
  494. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless-backup-stove.xml +552 -543
  495. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-mini-split-heat-pump-ductless.xml +16 -7
  496. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-multiple.xml +963 -938
  497. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-none.xml +33 -69
  498. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-portable-heater-gas-only.xml +530 -521
  499. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac-with-heating-electricity.xml +535 -0
  500. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-hvac-ptac-with-heating.xml → base-hvac-ptac-with-heating-natural-gas.xml} +23 -21
  501. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-ptac.xml +526 -517
  502. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-pthp.xml +541 -532
  503. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-33percent.xml +16 -7
  504. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-ceer.xml +526 -517
  505. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only-detailed-setpoints.xml +526 -517
  506. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-only.xml +16 -7
  507. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-heating.xml +535 -0
  508. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-room-ac-with-reverse-cycle.xml +542 -0
  509. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-seasons.xml +594 -583
  510. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-schedules.xml +586 -575
  511. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints-daily-setbacks.xml +18 -7
  512. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-setpoints.xml +18 -7
  513. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-oil-only.xml +530 -521
  514. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-stove-wood-pellets-only.xml +530 -521
  515. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized-allow-increased-fixed-capacities.xml +18 -7
  516. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-undersized.xml +18 -7
  517. data/example_files/resources/hpxml-measures/workflow/sample_files/base-hvac-wall-furnace-elec-only.xml +530 -521
  518. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-ceiling-fans.xml +18 -7
  519. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-holiday.xml +18 -7
  520. data/example_files/resources/hpxml-measures/workflow/sample_files/base-lighting-none.xml +18 -7
  521. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-AMY-2012.xml +18 -7
  522. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-baltimore-md.xml +27 -12
  523. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-capetown-zaf.xml +591 -576
  524. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-dallas-tx.xml +18 -7
  525. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-duluth-mn.xml +27 -12
  526. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-helena-mt.xml +582 -571
  527. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-honolulu-hi.xml +537 -526
  528. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-miami-fl.xml +18 -7
  529. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-phoenix-az.xml +537 -526
  530. data/example_files/resources/hpxml-measures/workflow/sample_files/base-location-portland-or.xml +601 -586
  531. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-balanced.xml +18 -7
  532. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-bath-kitchen-fans.xml +18 -7
  533. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-airflow-fraction-zero.xml +601 -587
  534. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-dse.xml +19 -7
  535. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-evap-cooler-only-ducted.xml +20 -7
  536. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-exhaust.xml +607 -0
  537. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis-supplemental-fan-supply.xml +607 -0
  538. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-cfis.xml +21 -7
  539. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv-atre-asre.xml +18 -7
  540. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-erv.xml +18 -7
  541. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust-rated-flow-rate.xml +18 -7
  542. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-exhaust.xml +18 -7
  543. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv-asre.xml +18 -7
  544. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-hrv.xml +18 -7
  545. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-multiple.xml +37 -19
  546. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-supply.xml +18 -7
  547. data/example_files/resources/hpxml-measures/workflow/sample_files/base-mechvent-whole-house-fan.xml +18 -7
  548. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-additional-properties.xml +590 -579
  549. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-none.xml +578 -0
  550. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-detailed-only.xml +632 -0
  551. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv-mixed.xml +614 -0
  552. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills-pv.xml +677 -0
  553. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-bills.xml +593 -0
  554. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-defaults.xml +27 -9
  555. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-emissions.xml +676 -665
  556. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery-scheduled.xml +616 -0
  557. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators-battery.xml +615 -0
  558. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-generators.xml +598 -587
  559. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-ground-conductivity.xml +586 -0
  560. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon.xml +18 -7
  561. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-large-uncommon2.xml +18 -7
  562. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-loads-none.xml +18 -7
  563. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-neighbor-shading.xml +18 -7
  564. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-shielding-of-home.xml +583 -572
  565. data/example_files/resources/hpxml-measures/workflow/sample_files/base-misc-usage-multiplier.xml +18 -7
  566. data/example_files/resources/hpxml-measures/workflow/sample_files/base-multiple-buildings.xml +1700 -1677
  567. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-ah.xml +622 -611
  568. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-garage.xml +697 -682
  569. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-pv-battery-lifetime-model.xml → base-pv-battery-round-trip-efficiency.xml} +20 -11
  570. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery-scheduled.xml +624 -0
  571. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-battery.xml +622 -611
  572. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery-scheduled.xml +640 -0
  573. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators-battery.xml +639 -0
  574. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv-generators.xml +623 -0
  575. data/example_files/resources/hpxml-measures/workflow/sample_files/base-pv.xml +606 -595
  576. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-all-10-mins.xml +582 -571
  577. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-smooth.xml +583 -572
  578. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-10-mins.xml +584 -0
  579. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic-vacancy.xml +583 -572
  580. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-occupancy-stochastic.xml +583 -572
  581. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-schedules.xml +581 -570
  582. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints-daily-setbacks.xml +581 -570
  583. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-detailed-setpoints.xml +581 -570
  584. data/example_files/resources/hpxml-measures/workflow/sample_files/base-schedules-simple.xml +636 -625
  585. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-calendar-year-custom.xml +18 -7
  586. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-custom.xml +27 -14
  587. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-daylight-saving-disabled.xml +21 -10
  588. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-runperiod-1-month.xml +21 -10
  589. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-dhw-tank-heat-pump-detailed-operating-modes.xml → base-simcontrol-temperature-capacitance-multiplier.xml} +25 -13
  590. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-10-mins.xml +584 -0
  591. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins-occupancy-stochastic-60-mins.xml +584 -0
  592. data/example_files/resources/hpxml-measures/workflow/sample_files/base-simcontrol-timestep-10-mins.xml +18 -7
  593. data/example_files/resources/hpxml-measures/workflow/sample_files/{base-dhw-tank-heat-pump-detailed-setpoints.xml → base-simcontrol-timestep-30-mins.xml} +25 -14
  594. data/example_files/resources/hpxml-measures/workflow/sample_files/base.xml +18 -7
  595. data/example_files/resources/hpxml-measures/workflow/template-build-and-run-hpxml-with-stochastic-occupancy.osw +18 -13
  596. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy-subset.osw +64 -0
  597. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml-with-stochastic-occupancy.osw +12 -7
  598. data/example_files/resources/hpxml-measures/workflow/template-run-hpxml.osw +8 -24
  599. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AC.xml +366 -358
  600. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L100AL.xml +369 -361
  601. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AC.xml +369 -361
  602. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L110AL.xml +369 -361
  603. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AC.xml +369 -361
  604. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L120AL.xml +369 -361
  605. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AC.xml +369 -361
  606. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L130AL.xml +369 -361
  607. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AC.xml +311 -303
  608. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L140AL.xml +311 -303
  609. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AC.xml +327 -319
  610. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L150AL.xml +327 -319
  611. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AC.xml +332 -324
  612. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L155AL.xml +332 -324
  613. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AC.xml +341 -333
  614. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L160AL.xml +341 -333
  615. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AC.xml +369 -361
  616. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L170AL.xml +369 -361
  617. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AC.xml +369 -361
  618. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L200AL.xml +369 -361
  619. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AC.xml +369 -361
  620. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L202AL.xml +369 -361
  621. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L302XC.xml +383 -379
  622. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L304XC.xml +383 -379
  623. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L322XC.xml +538 -534
  624. data/example_files/resources/hpxml-measures/workflow/tests/ASHRAE_Standard_140/L324XC.xml +550 -546
  625. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results.csv +444 -410
  626. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_ashrae_140.csv +8 -8
  627. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_bills.csv +444 -410
  628. data/example_files/resources/hpxml-measures/workflow/tests/compare.py +18 -4
  629. data/example_files/resources/hpxml-measures/workflow/tests/hpxml_translator_test.rb +163 -392
  630. data/example_files/scripts/convert_urbanopt_to_disco.py +130 -0
  631. data/example_files/scripts/default_control_changes.csv +8 -0
  632. data/example_files/scripts/default_voltage_regulators.csv +3 -0
  633. data/example_files/scripts/read_data.py +331 -0
  634. data/example_files/visualization/input_visualization_feature.html +172 -81
  635. data/example_files/visualization/input_visualization_scenario.html +178 -82
  636. data/example_files/xml_building/17/README.md +2 -2
  637. data/example_files/xml_building/17/unit 1.xml +40 -41
  638. data/example_files/xml_building/17/unit 2.xml +35 -36
  639. data/example_files/xml_building/17/unit 3.xml +35 -36
  640. data/example_files/xml_building/17/unit 4.xml +41 -42
  641. data/lib/uo_cli/version.rb +2 -2
  642. data/lib/uo_cli.rb +597 -97
  643. data/uo_cli.gemspec +6 -5
  644. metadata +122 -36
  645. data/example_files/residential/exhaust.tsv +0 -3
  646. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/hvac_equipment_efficiency.csv +0 -493
  647. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/water_heater_efficiency.csv +0 -157
  648. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/HPXMLvalidator.xml +0 -620
  649. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/validator.rb +0 -107
  650. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.rb +0 -450
  651. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.xml +0 -85
  652. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/resources/constants.rb +0 -72
  653. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/tests/hpxml_output_report_test.rb +0 -290
  654. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_10kW.csv +0 -8761
  655. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_1kW.csv +0 -8761
  656. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_None.csv +0 -8761
  657. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_hvac_sizing.csv +0 -410
@@ -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