urbanopt-cli 0.8.2 → 0.9.0

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