urbanopt-cli 0.8.0 → 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 (657) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +6 -4
  3. data/CHANGELOG.md +33 -0
  4. data/CMakeLists.txt +7 -7
  5. data/FindOpenStudioSDK.cmake +6 -6
  6. data/Gemfile +3 -1
  7. data/README.md +12 -3
  8. data/example_files/Gemfile +22 -16
  9. data/example_files/Gemfile.lock +177 -0
  10. data/example_files/base_workflow_res.osw +57 -14
  11. data/example_files/class_project_coincident.json +1322 -0
  12. data/example_files/class_project_diverse.json +1322 -0
  13. data/example_files/disco/config.json +42 -0
  14. data/example_files/disco/cost_database.xlsx +0 -0
  15. data/example_files/disco/technical_catalog.json +12126 -0
  16. data/example_files/example_project.json +9 -14
  17. data/example_files/example_project_combined.json +10 -22
  18. data/example_files/example_project_with_PV.json +8 -1
  19. data/example_files/example_project_with_electric_network.json +8 -1
  20. data/example_files/example_project_with_streets.json +9 -2
  21. data/example_files/mappers/Baseline.rb +293 -263
  22. data/example_files/mappers/ChilledWaterStorage.rb +98 -0
  23. data/example_files/mappers/ClassProject.rb +110 -0
  24. data/example_files/mappers/CreateBar.rb +1 -0
  25. data/example_files/mappers/HighEfficiency.rb +13 -11
  26. data/example_files/mappers/PeakHoursMelsShedding.rb +72 -0
  27. data/example_files/mappers/PeakHoursThermostatAdjust.rb +78 -0
  28. data/example_files/mappers/ThermalStorage.rb +1 -0
  29. data/example_files/mappers/base_workflow.osw +55 -14
  30. data/example_files/mappers/class_project_workflow.osw +328 -0
  31. data/example_files/mappers/createbar_workflow.osw +16 -16
  32. data/example_files/measures/BuildResidentialModel/measure.rb +7 -1
  33. data/example_files/measures/BuildResidentialModel/measure.xml +1313 -706
  34. data/example_files/opendss/electrical_database.json +1446 -1446
  35. data/example_files/python_deps/dependencies.json +5 -0
  36. data/example_files/python_deps/install_python.ps1 +96 -0
  37. data/example_files/python_deps/install_python.sh +120 -0
  38. data/example_files/residential/clothes_dryer.tsv +11 -11
  39. data/example_files/residential/clothes_washer.tsv +3 -3
  40. data/example_files/residential/dishwasher.tsv +3 -3
  41. data/example_files/resources/hpxml-measures/.github/pull_request_template.md +0 -1
  42. data/example_files/resources/hpxml-measures/.github/workflows/config.yml +8 -21
  43. data/example_files/resources/hpxml-measures/.gitignore +2 -0
  44. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.rb +1272 -1094
  45. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/measure.xml +978 -659
  46. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/resources/geometry.rb +52 -74
  47. data/example_files/resources/hpxml-measures/BuildResidentialHPXML/tests/build_residential_hpxml_test.rb +77 -140
  48. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.rb +30 -27
  49. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/measure.xml +32 -13
  50. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/resources/schedules.rb +55 -51
  51. data/example_files/resources/hpxml-measures/BuildResidentialScheduleFile/tests/build_residential_schedule_file_test.rb +89 -16
  52. data/example_files/resources/hpxml-measures/Changelog.md +65 -0
  53. data/example_files/resources/hpxml-measures/Gemfile +2 -4
  54. data/example_files/resources/hpxml-measures/Gemfile.lock +2 -13
  55. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.rb +276 -300
  56. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/measure.xml +221 -215
  57. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/airflow.rb +215 -170
  58. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/battery.rb +108 -16
  59. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constants.rb +24 -44
  60. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/constructions.rb +564 -197
  61. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/cambium/README.md +8 -8
  62. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/energyplus.rb +1 -0
  63. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/geometry.rb +7 -55
  64. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hotwater_appliances.rb +24 -19
  65. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml.rb +541 -211
  66. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_defaults.rb +300 -172
  67. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXML.xsd +0 -2
  68. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLBaseElements.xsd +230 -141
  69. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schema/HPXMLDataTypes.xsd +145 -137
  70. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/EPvalidator.xml +191 -97
  71. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/iso-schematron.xsd +391 -0
  72. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac.rb +194 -198
  73. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hvac_sizing.rb +140 -145
  74. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/lighting.rb +11 -11
  75. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/location.rb +33 -1
  76. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/materials.rb +4 -4
  77. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/meta_measure.rb +17 -9
  78. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/misc_loads.rb +14 -12
  79. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/output.rb +39 -17
  80. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/psychrometrics.rb +1 -1
  81. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedule_files/battery.csv +8761 -0
  82. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/schedules.rb +114 -57
  83. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/simcontrols.rb +1 -0
  84. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/utility_bills.rb +148 -0
  85. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/version.rb +2 -2
  86. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/waterheater.rb +85 -127
  87. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/weather.rb +26 -32
  88. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlhelper.rb +2 -14
  89. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/xmlvalidator.rb +67 -0
  90. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_airflow.rb +117 -56
  91. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_battery.rb +141 -14
  92. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_defaults.rb +453 -344
  93. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_enclosure.rb +124 -20
  94. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_generator.rb +1 -1
  95. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hotwater_appliance.rb +28 -32
  96. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac.rb +172 -79
  97. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_hvac_sizing.rb +54 -8
  98. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_lighting.rb +3 -3
  99. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_location.rb +4 -4
  100. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_miscloads.rb +7 -7
  101. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_pv.rb +1 -1
  102. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_schedules.rb +6 -9
  103. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_simcontrols.rb +8 -8
  104. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_validation.rb +213 -95
  105. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_water_heater.rb +1 -10
  106. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/tests/test_weather.rb +76 -0
  107. data/example_files/resources/hpxml-measures/README.md +2 -3
  108. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.rb +585 -287
  109. data/example_files/resources/hpxml-measures/ReportSimulationOutput/measure.xml +304 -352
  110. data/example_files/resources/hpxml-measures/ReportSimulationOutput/tests/output_report_test.rb +404 -279
  111. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.rb +222 -501
  112. data/example_files/resources/hpxml-measures/ReportUtilityBills/measure.xml +137 -200
  113. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Annual Charge.json +649 -0
  114. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate Min Monthly Charge.json +649 -0
  115. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Flat Rate.json +647 -0
  116. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate Min Annual Charge.json +8776 -0
  117. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate Min Monthly Charge.json +8776 -0
  118. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Real-Time Pricing Rate.json +8774 -0
  119. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate Min Annual Charge.json +659 -0
  120. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate Min Monthly Charge.json +659 -0
  121. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Rate.json +657 -0
  122. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate Min Annual Charge.json +670 -0
  123. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate Min Monthly Charge.json +670 -0
  124. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Tiered Time-of-Use Rate.json +668 -0
  125. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate Min Annual Charge.json +655 -0
  126. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate Min Monthly Charge.json +655 -0
  127. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/Sample Time-of-Use Rate.json +653 -0
  128. data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/detailed_rates/openei_rates.zip +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/validation_schema.yaml +11 -11
  627. data/example_files/visualization/input_visualization_feature.html +418 -90
  628. data/example_files/visualization/input_visualization_scenario.html +297 -93
  629. data/example_files/xml_building/17/README.md +2 -2
  630. data/example_files/xml_building/17/unit 1.xml +40 -41
  631. data/example_files/xml_building/17/unit 2.xml +35 -36
  632. data/example_files/xml_building/17/unit 3.xml +35 -36
  633. data/example_files/xml_building/17/unit 4.xml +41 -42
  634. data/lib/uo_cli/version.rb +1 -1
  635. data/lib/uo_cli.rb +657 -148
  636. data/scripts/setup-env.bat +6 -7
  637. data/uo_cli.gemspec +6 -5
  638. metadata +121 -36
  639. data/example_files/residential/exhaust.tsv +0 -3
  640. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/hvac_equipment_efficiency.csv +0 -493
  641. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/data/water_heater_efficiency.csv +0 -157
  642. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/hpxml_schematron/HPXMLvalidator.xml +0 -620
  643. data/example_files/resources/hpxml-measures/HPXMLtoOpenStudio/resources/validator.rb +0 -107
  644. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.rb +0 -450
  645. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/measure.xml +0 -85
  646. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/resources/constants.rb +0 -72
  647. data/example_files/resources/hpxml-measures/ReportHPXMLOutput/tests/hpxml_output_report_test.rb +0 -290
  648. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_10kW.csv +0 -8761
  649. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_1kW.csv +0 -8761
  650. data/example_files/resources/hpxml-measures/ReportUtilityBills/tests/PV_None.csv +0 -8761
  651. data/example_files/resources/hpxml-measures/workflow/tests/base_results/results_hvac_sizing.csv +0 -410
  652. /data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/Average_retail_price_of_electricity.csv +0 -0
  653. /data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/HouseholdConsumption.csv +0 -0
  654. /data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/NG_PRI_SUM_A_EPG0_PRS_DMCF_A.csv +0 -0
  655. /data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/PET_PRI_WFR_A_EPD2F_PRS_DPGAL_W.csv +0 -0
  656. /data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/PET_PRI_WFR_A_EPLLPA_PRS_DPGAL_W.csv +0 -0
  657. /data/example_files/resources/hpxml-measures/ReportUtilityBills/resources/{Data/UtilityRates → simple_rates}/README.md +0 -0
data/lib/uo_cli.rb CHANGED
@@ -59,11 +59,14 @@ module URBANopt
59
59
  class UrbanOptCLI
60
60
  COMMAND_MAP = {
61
61
  'create' => 'Make new things - project directory or files',
62
+ 'install_python' => 'Install python and other dependencies to run OpenDSS and DISCO analysis',
63
+ 'update' => 'Update files in an existing URBANopt project',
62
64
  'run' => 'Use files in your directory to simulate district energy use',
63
65
  'process' => 'Post-process URBANopt simulations for additional insights',
64
66
  'visualize' => 'Visualize and compare results for features and scenarios',
65
67
  'validate' => 'Validate results with custom rules',
66
68
  'opendss' => 'Run OpenDSS simulation',
69
+ 'disco' => 'Run DISCO analysis',
67
70
  'rnm' => 'Run RNM simulation',
68
71
  'delete' => 'Delete simulations for a specified scenario',
69
72
  'des_params' => 'Make a DES system parameters config file',
@@ -85,7 +88,7 @@ module URBANopt
85
88
  # opt :no_pager, "Disable paging"
86
89
  stop_on COMMAND_MAP.keys
87
90
  banner "\nCommands:"
88
- COMMAND_MAP.each { |cmd, desc| banner format(' %-10s %s', cmd, desc) }
91
+ COMMAND_MAP.each { |cmd, desc| banner format(' %-14s %s', cmd, desc) }
89
92
  banner "\nFor help with a specific command: uo <command> --help"
90
93
  banner "\nAdditional config options can be set with the 'runner.conf' file inside your project folder"
91
94
  banner 'Fewer warnings are presented when using full paths and the user is not inside the project folder'
@@ -127,12 +130,25 @@ module URBANopt
127
130
  opt :electric, "\nCreate default project with FeatureFile containing electrical network, used for OpenDSS analysis\n" \
128
131
  'Example: uo create --project-folder urbanopt_example_project --electric', short: :l
129
132
 
130
- opt :streets, "\nCreate default project wiht FeatureFile containing streets, used for RNM analysis\n" \
133
+ opt :disco, "\nCreate default project with FeatureFile containing electrical network, and scenarios for DISCO cost upgrade analysis\n"\
134
+ 'Example: uo create --project-folder urbanopt_example_project --disco', short: :a
135
+
136
+ opt :streets, "\nCreate default project with FeatureFile containing streets, used for RNM analysis\n" \
131
137
  'Example: uo create --project-folder urbanopt_example_project --streets', short: :t
132
138
 
133
139
  opt :photovoltaic, "\nCreate default project with FeatureFile containing community photovoltaic for the district and ground-mount photovoltaic associated with buildings, used for REopt analysis \n" \
134
140
  'Example: uo create --project-folder urbanopt_example_project --photovoltaic', short: :v
135
141
 
142
+ opt :class_coincident, "\nCreate default class project with buildings that have coincident schedules \n" \
143
+ "Refer to https://docs.urbanopt.net/ for more details about the class project \n" \
144
+ "Used with --project-folder\n" \
145
+ "Example: uo create --project-folder urbanopt_example_project --class-coincident\n", short: :C
146
+
147
+ opt :class_diverse, "\nCreate default class project with buildings that have diverse schedules \n" \
148
+ "Refer to https://docs.urbanopt.net/ for more details about the class project \n" \
149
+ "Used with --project-folder\n" \
150
+ "Example: uo create --project-folder urbanopt_example_project --class-diverse\n", short: :D
151
+
136
152
  opt :empty, "\nUse with --project-folder argument to create an empty project folder\n" \
137
153
  "Then add your own Feature file in the project directory you created,\n" \
138
154
  "add Weather files in the weather folder and add OpenStudio models of Features\n" \
@@ -151,13 +167,33 @@ module URBANopt
151
167
  "Use the FeatureID from your FeatureFile\n" \
152
168
  "Requires 'scenario-file' also be specified, to say which FeatureFile will create the ScenarioFile\n" \
153
169
  "Example: uo create --single-feature 2 --scenario-file example_project.json\n", type: String, short: :i
154
-
170
+
155
171
  opt :reopt_scenario_file, "\nCreate a ScenarioFile that includes a column defining the REopt assumptions file\n" \
156
172
  "Specify the existing ScenarioFile that you want to extend with REopt functionality\n" \
157
173
  "Example: uo create --reopt-scenario-file baseline_scenario.csv\n", type: String, short: :r
158
174
  end
159
175
  end
160
176
 
177
+ # Define commands to install python
178
+ def opt_install_python
179
+ @subopts = Optimist.options do
180
+ banner "\nURBANopt #{@command}:\n \n"
181
+ end
182
+ end
183
+
184
+ # Update project
185
+ def opt_update
186
+ @subopts = Optimist.options do
187
+ banner "\nURBANopt #{@command}:\n \n"
188
+
189
+ opt :existing_project_folder, "\Specify existing project folder name to update files \n" \
190
+ 'Example: uo update --existing-project-folder urbanopt_example_project --new-project-directory location/to/new_urbanopt_example_project', type: String, short: :e
191
+
192
+ opt :new_project_directory, "\Specify location for updated URBANopt project. \n" \
193
+ 'Example: uo update --existing-project-folder urbanopt_example_project --new-project-directory location/to/new_urbanopt_example_project', type: String, short: :n
194
+ end
195
+ end
196
+
161
197
  # Define running commands
162
198
  def opt_run
163
199
  @subopts = Optimist.options do
@@ -173,7 +209,7 @@ module URBANopt
173
209
 
174
210
  opt :num_parallel, "\nOPTIONAL: Run URBANopt simulations in parallel using <num_parallel> cores\n" \
175
211
  "Adjusts value of 'num_parallel' in the 'runner.conf' file\n" \
176
- "Example: uo run --num-parallel 2\n", default: 2, short: :n
212
+ "Example: uo run --num-parallel 2\n", type: Integer, short: :n
177
213
  end
178
214
  end
179
215
 
@@ -220,11 +256,35 @@ module URBANopt
220
256
  opt :reopt, "\nRun with additional REopt functionality.\n" \
221
257
  'Example: uo opendss --scenario baseline_scenario.csv --feature example_project.json --reopt', short: :r
222
258
 
259
+ opt :rnm, "\nUse RNM-generated DSS files in this analysis\n" \
260
+ 'Example: uo opendss --scenario baseline_scenario.csv --feature example_project.json --rnm', short: :m
261
+
223
262
  opt :config, "\nRun OpenDSS using a json config file to specify the above settings.\n" \
224
263
  'Example: uo opendss --config path/to/config.json', type: String, short: :c
225
264
  end
226
265
  end
227
266
 
267
+ # Define DISCO commands
268
+ def opt_disco
269
+ @subopts = Optimist.options do
270
+ banner "\nURBANopt #{@command}:\n\n"
271
+
272
+ opt :scenario, "\nRun DISCO simulations for <scenario>\n" \
273
+ "Requires --feature also be specified\n" \
274
+ 'Example: uo disco --scenario baseline_scenario-2.csv --feature example_project.json', default: 'baseline_scenario.csv', short: :s
275
+
276
+ opt :feature, "\nRun DISCO simulations according to <featurefile>\n" \
277
+ "Requires --scenario also be specified\n" \
278
+ 'Example: uo disco --scenario baseline_scenario.csv --feature example_project.json', default: 'example_project_with_electric_network.json', short: :f
279
+
280
+ opt :cost_database, "\nSpecify cost database for electric equipment upgrade\n" \
281
+ 'Example: uo disco --scenario baseline_scenario.csv --feature example_project.json --cost_database cost_database.xlsx', default: 'cost_database.xlsx', short: :c
282
+
283
+ opt :technical_catalog, "\nSpecify technical catalog for thermal upgrade\n" \
284
+ 'Example: uo disco --scenario baseline_scenario.csv --feature example_project.json --technical_catalog technical_catalog.json', short: :t
285
+ end
286
+ end
287
+
228
288
  # Define RNM commands
229
289
  def opt_rnm
230
290
  @subopts = Optimist.options do
@@ -261,6 +321,8 @@ module URBANopt
261
321
 
262
322
  opt :opendss, "\nPost-process with OpenDSS"
263
323
 
324
+ opt :disco, "\nPost-process with DISCO"
325
+
264
326
  opt :reopt_scenario, "\nOptimize for entire scenario with REopt. Used with the --reopt-scenario-assumptions-file to specify the assumptions to use.\n" \
265
327
  'Example: uo process --reopt-scenario'
266
328
 
@@ -414,31 +476,31 @@ module URBANopt
414
476
  end
415
477
 
416
478
  feature_file = URBANopt::GeoJSON::GeoFile.from_file(featurefile)
417
- if @opthash.subopts[:reopt] == true || @opthash.subopts[:reopt_scenario] == true || @opthash.subopts[:reopt_feature] == true
418
- # TODO: Better way of grabbing assumptions file than the first file in the folder
419
- reopt_files_dir_contents_list = Dir.children(reopt_files_dir.to_s)
420
- reopt_assumptions_filename = File.basename(reopt_files_dir_contents_list[0])
479
+ if @opthash.subopts[:reopt] == true || @opthash.subopts[:reopt_scenario] == true || @opthash.subopts[:reopt_feature] == true
480
+ # TODO: Better way of grabbing assumptions file than the first file in the folder
481
+ reopt_files_dir_contents_list = Dir.children(reopt_files_dir.to_s)
482
+ reopt_assumptions_filename = File.basename(reopt_files_dir_contents_list[0])
421
483
  scenario_output = URBANopt::Scenario::REoptScenarioCSV.new(
422
- @scenario_name.downcase,
423
- @root_dir,
424
- run_dir,
425
- feature_file,
426
- mapper_files_dir,
427
- csv_file,
428
- num_header_rows,
429
- reopt_files_dir,
484
+ @scenario_name.downcase,
485
+ @root_dir,
486
+ run_dir,
487
+ feature_file,
488
+ mapper_files_dir,
489
+ csv_file,
490
+ num_header_rows,
491
+ reopt_files_dir,
430
492
  reopt_assumptions_filename
431
- )
432
- else
493
+ )
494
+ else
433
495
  scenario_output = URBANopt::Scenario::ScenarioCSV.new(
434
- @scenario_name.downcase,
435
- @root_dir,
436
- run_dir,
437
- feature_file,
438
- mapper_files_dir,
439
- csv_file,
496
+ @scenario_name.downcase,
497
+ @root_dir,
498
+ run_dir,
499
+ feature_file,
500
+ mapper_files_dir,
501
+ csv_file,
440
502
  num_header_rows
441
- )
503
+ )
442
504
  end
443
505
  scenario_output
444
506
  end
@@ -487,12 +549,12 @@ module URBANopt
487
549
  end
488
550
  end
489
551
 
490
- # Write new ScenarioFile with REopt column
491
- # params \
492
- # +existing_scenario_file+:: _string_ - Name of existing ScenarioFile
493
- def self.create_reopt_scenario_file(existing_scenario_file)
494
- existing_path, existing_name = File.split(File.expand_path(existing_scenario_file))
495
- # make reopt folder (if it does not exist)
552
+ # Write new ScenarioFile with REopt column
553
+ # params \
554
+ # +existing_scenario_file+:: _string_ - Name of existing ScenarioFile
555
+ def self.create_reopt_scenario_file(existing_scenario_file)
556
+ existing_path, existing_name = File.split(File.expand_path(existing_scenario_file))
557
+ # make reopt folder (if it does not exist)
496
558
  unless Dir.exist?(File.join(existing_path, 'reopt'))
497
559
  Dir.mkdir File.join(existing_path, 'reopt')
498
560
  # copy reopt files from cli examples
@@ -502,18 +564,18 @@ module URBANopt
502
564
  Pathname.new(reopt_files).children.each { |reopt_file| FileUtils.cp(reopt_file, File.join(existing_path, 'reopt')) }
503
565
  end
504
566
  end
505
- end
506
-
507
- table = CSV.read(existing_scenario_file, headers: true, col_sep: ',')
508
- # Add another column, row by row:
509
- table.each do |row|
510
- row['REopt Assumptions'] = 'multiPV_assumptions.json'
511
- end
567
+ end
568
+
569
+ table = CSV.read(existing_scenario_file, headers: true, col_sep: ',')
570
+ # Add another column, row by row:
571
+ table.each do |row|
572
+ row['REopt Assumptions'] = 'multiPV_assumptions.json'
573
+ end
512
574
  # write new file (name it REopt + existing scenario name)
513
- CSV.open(File.join(existing_path, 'REopt_' + existing_name), 'w') do |f|
514
- f << table.headers
515
- table.each { |row| f << row }
516
- end
575
+ CSV.open(File.join(existing_path, "REopt_#{existing_name}"), 'w') do |f|
576
+ f << table.headers
577
+ table.each { |row| f << row }
578
+ end
517
579
  end
518
580
 
519
581
  # Create project folder
@@ -521,7 +583,7 @@ module URBANopt
521
583
  # +dir_name+:: _string_ Name of new project folder
522
584
  #
523
585
  # Includes weather for example location, a base workflow file, and mapper files to show a baseline and a high-efficiency option.
524
- def self.create_project_folder(dir_name, empty_folder = false, overwrite_project = false)
586
+ def self.create_project_folder(dir_name, empty_folder: false, overwrite_project: false)
525
587
  case overwrite_project
526
588
  when true
527
589
  if Dir.exist?(dir_name)
@@ -544,12 +606,26 @@ module URBANopt
544
606
  Dir.mkdir File.join(dir_name, 'mappers')
545
607
  Dir.mkdir File.join(dir_name, 'osm_building')
546
608
  Dir.mkdir File.join(dir_name, 'visualization')
547
- if @opthash.subopts[:electric] == true
609
+ if @opthash.subopts[:electric] == true || @opthash.subopts[:disco] == true
610
+ # make opendss folder
548
611
  Dir.mkdir File.join(dir_name, 'opendss')
612
+ if @opthash.subopts[:disco] == true
613
+ # make disco folder
614
+ Dir.mkdir File.join(dir_name, 'disco')
615
+ end
549
616
  end
550
617
 
551
618
  # copy config file
552
619
  FileUtils.cp(File.join(path_item, 'runner.conf'), dir_name)
620
+ # If the env var is set, change the num_parallel value to be what the env var is set to
621
+ if ENV['UO_NUM_PARALLEL']
622
+ runner_file_path = File.join(dir_name, 'runner.conf')
623
+ runner_conf_hash = JSON.parse(File.read(runner_file_path))
624
+ runner_conf_hash['num_parallel'] = ENV['UO_NUM_PARALLEL'].to_i
625
+ File.open(runner_file_path, 'w+') do |f|
626
+ f << runner_conf_hash.to_json
627
+ end
628
+ end
553
629
 
554
630
  # copy gemfile
555
631
  FileUtils.cp(File.join(path_item, 'Gemfile'), dir_name)
@@ -565,12 +641,18 @@ module URBANopt
565
641
  viz_files = File.join(path_item, 'visualization')
566
642
  Pathname.new(viz_files).children.each { |viz_file| FileUtils.cp(viz_file, File.join(dir_name, 'visualization')) }
567
643
 
568
- if @opthash.subopts[:electric] == true
569
- FileUtils.cp(File.join(path_item, 'example_project_with_electric_network.json'), dir_name)
570
- # also create opendss folder
644
+ if @opthash.subopts[:electric] == true || @opthash.subopts[:disco] == true
645
+ # also copy opendss files
571
646
  dss_files = File.join(path_item, 'opendss')
572
647
  Pathname.new(dss_files).children.each { |file| FileUtils.cp(file, File.join(dir_name, 'opendss')) }
573
-
648
+ if @opthash.subopts[:electric] == true
649
+ FileUtils.cp(File.join(path_item, 'example_project_with_electric_network.json'), dir_name)
650
+ elsif @opthash.subopts[:disco] == true
651
+ # TODO: update this once there is a FeatureFile for Disco
652
+ FileUtils.cp(File.join(path_item, 'example_project_with_electric_network.json'), dir_name)
653
+ disco_files = File.join(path_item, 'disco')
654
+ Pathname.new(disco_files).children.each { |file| FileUtils.cp(file, File.join(dir_name, 'disco')) }
655
+ end
574
656
  elsif @opthash.subopts[:streets] == true
575
657
  FileUtils.cp(File.join(path_item, 'example_project_with_streets.json'), dir_name)
576
658
  elsif @opthash.subopts[:photovoltaic] == true
@@ -580,7 +662,7 @@ module URBANopt
580
662
  case @opthash.subopts[:floorspace]
581
663
  when false
582
664
 
583
- if @opthash.subopts[:electric] != true && @opthash.subopts[:streets] != true && @opthash.subopts[:photovoltaic] != true
665
+ if @opthash.subopts[:electric] != true && @opthash.subopts[:streets] != true && @opthash.subopts[:photovoltaic] != true && @opthash.subopts[:disco] != true
584
666
  # copy feature file
585
667
  FileUtils.cp(File.join(path_item, 'example_project.json'), dir_name)
586
668
  end
@@ -633,6 +715,40 @@ module URBANopt
633
715
  FileUtils.cp(File.join(path_item, 'osm_building/9.osm'), File.join(dir_name, 'osm_building'))
634
716
  end
635
717
 
718
+ if @opthash.subopts[:class_coincident]
719
+ # copy residential files
720
+ FileUtils.cp_r(File.join(path_item, 'residential'), File.join(dir_name, 'mappers', 'residential'))
721
+ FileUtils.cp_r(File.join(path_item, 'measures'), File.join(dir_name, 'measures'))
722
+ FileUtils.cp_r(File.join(path_item, 'resources'), File.join(dir_name, 'resources'))
723
+ FileUtils.cp_r(File.join(path_item, 'xml_building'), File.join(dir_name, 'xml_building'))
724
+ # copy class project files
725
+ FileUtils.cp(File.join(path_item, 'class_project_coincident.json'), dir_name)
726
+ FileUtils.cp(File.join(path_item, 'mappers/class_project_workflow.osw'), File.join(dir_name, 'mappers', 'base_workflow.osw'))
727
+ FileUtils.cp(File.join(path_item, 'mappers/ClassProject.rb'), File.join(dir_name, 'mappers'))
728
+
729
+ if File.exist?(File.join(dir_name, 'example_project.json'))
730
+ FileUtils.remove(File.join(dir_name, 'example_project.json'))
731
+ end
732
+
733
+ end
734
+
735
+ if @opthash.subopts[:class_diverse]
736
+ # copy residential files
737
+ FileUtils.cp_r(File.join(path_item, 'residential'), File.join(dir_name, 'mappers', 'residential'))
738
+ FileUtils.cp_r(File.join(path_item, 'measures'), File.join(dir_name, 'measures'))
739
+ FileUtils.cp_r(File.join(path_item, 'resources'), File.join(dir_name, 'resources'))
740
+ FileUtils.cp_r(File.join(path_item, 'xml_building'), File.join(dir_name, 'xml_building'))
741
+ # copy class project files
742
+ FileUtils.cp(File.join(path_item, 'class_project_diverse.json'), dir_name)
743
+ FileUtils.cp(File.join(path_item, 'mappers/class_project_workflow.osw'), File.join(dir_name, 'mappers', 'base_workflow.osw'))
744
+ FileUtils.cp(File.join(path_item, 'mappers/ClassProject.rb'), File.join(dir_name, 'mappers'))
745
+
746
+ if File.exist?(File.join(dir_name, 'example_project.json'))
747
+ FileUtils.remove(File.join(dir_name, 'example_project.json'))
748
+ end
749
+
750
+ end
751
+
636
752
  if @opthash.subopts[:combined]
637
753
  # copy residential files
638
754
  FileUtils.cp_r(File.join(path_item, 'residential'), File.join(dir_name, 'mappers', 'residential'))
@@ -668,84 +784,355 @@ module URBANopt
668
784
  end
669
785
  end
670
786
 
671
- # Check Python
787
+ # Update an existing URBANopt Project
672
788
  # params\
789
+ # +existing_project_folder+:: _string_ Name of existing project folder
790
+ # +new_project_directory+:: _string_ Location of updated URBANopt project
673
791
  #
674
- # Check that sys has python 3.7+ installed
675
- def self.check_python
676
- results = { python: false, message: '' }
792
+ # Includes weather for example location, a base workflow file, and mapper files to show a baseline and a high-efficiency option.
793
+ def self.update_project(existing_project_folder, new_project_directory)
794
+ path = File.expand_path(existing_project_folder)
795
+ new_path = Pathname.new(new_project_directory)
796
+
797
+ if Dir.exist?(new_path)
798
+ abort("\nERROR: there is already a directory here named #{new_path}... aborting\n---\n\n")
799
+ end
800
+
801
+ FileUtils.copy_entry(path, new_path)
802
+
803
+ $LOAD_PATH.each do |path_item|
804
+ if path_item.to_s.end_with?('example_files')
805
+
806
+ # copy gemfile
807
+ FileUtils.cp_r(File.join(path_item, 'Gemfile'), new_path, remove_destination: true)
808
+
809
+ # copy validation schema
810
+ FileUtils.cp_r(File.join(path_item, 'validation_schema.yaml'), new_path, remove_destination: true)
811
+
812
+ # copy config file
813
+ FileUtils.cp_r(File.join(path_item, 'runner.conf'), new_path, remove_destination: true)
814
+ # If the env var is set, change the num_parallel value to be what the env var is set to
815
+ # TODO: make this into a function...it's used in 2 places
816
+ if ENV['UO_NUM_PARALLEL']
817
+ runner_file_path = File.join(new_path, 'runner.conf')
818
+ runner_conf_hash = JSON.parse(File.read(runner_file_path))
819
+ runner_conf_hash['num_parallel'] = ENV['UO_NUM_PARALLEL'].to_i
820
+ File.open(runner_file_path, 'w+') do |f|
821
+ f << runner_conf_hash.to_json
822
+ end
823
+ end
824
+
825
+ # Replace standard mappers
826
+ # Note: this also copies createBar and Floorspace without checking project type (for now)
827
+ mappers = File.join(path_item, 'mappers')
828
+ Pathname.new(mappers).children.each { |mapper| FileUtils.cp_r(mapper, File.join(new_path, 'mappers'), remove_destination: true) }
829
+
830
+ # Replace OSM files
831
+ if Dir.exist?(File.join(path, 'osm_building'))
832
+ Pathname.new(File.join(path_item, 'osm_building')).children.each { |res| FileUtils.cp_r(res, File.join(new_path, 'osm_building'), remove_destination: true) }
833
+ end
834
+
835
+ # Replace weather
836
+ if Dir.exist?(File.join(path, 'weather'))
837
+ Pathname.new(File.join(path_item, 'weather')).children.each { |weather_file| FileUtils.cp_r(weather_file, File.join(new_path, 'weather'), remove_destination: true) }
838
+ end
839
+
840
+ # Replace visualization files
841
+ Pathname.new(File.join(path_item, 'visualization')).children.each { |viz| FileUtils.cp_r(viz, File.join(new_path, 'visualization'), remove_destination: true) }
842
+
843
+ # Replace Residential files
844
+ if Dir.exist?(File.join(path, 'residential'))
845
+ Pathname.new(File.join(path_item, 'residential')).children.each { |res| FileUtils.cp_r(res, File.join(new_path, 'mappers', 'residential'), remove_destination: true) }
846
+ end
847
+ if Dir.exist?(File.join(path, 'measures'))
848
+ Pathname.new(File.join(path_item, 'measures')).children.each { |res| FileUtils.cp_r(res, File.join(new_path, 'measures'), remove_destination: true) }
849
+ end
850
+ if Dir.exist?(File.join(path, 'resources'))
851
+ Pathname.new(File.join(path_item, 'resources')).children.each { |res| FileUtils.cp_r(res, File.join(new_path, 'resources'), remove_destination: true) }
852
+ end
853
+ # adjust for residential workflow
854
+ FileUtils.cp_r(File.join(path_item, 'base_workflow_res.osw'), File.join(new_path, 'mappers', 'base_workflow.osw'), remove_destination: true)
855
+ if Dir.exist?(File.join(path, 'xml_building'))
856
+ Pathname.new(File.join(path_item, 'xml_building')).children.each { |res| FileUtils.cp_r(res, File.join(new_path, 'xml_building'), remove_destination: true) }
857
+ end
858
+
859
+ # Replace Reopt assumption files
860
+ if Dir.exist?(File.join(path, 'reopt'))
861
+ Pathname.new(File.join(path_item, 'reopt')).children.each { |reopt_file| FileUtils.cp_r(reopt_file, File.join(new_path, 'reopt'), remove_destination: true) }
862
+ end
863
+
864
+ # Replace OpenDSS files
865
+ if Dir.exist?(File.join(path, 'opendss'))
866
+ Pathname.new(File.join(path_item, 'opendss')).children.each { |opendss_file| FileUtils.cp_r(opendss_file, File.join(new_path, 'opendss'), remove_destination: true) }
867
+ end
868
+
869
+ if Dir.exist?(File.join(path, 'disco'))
870
+ Pathname.new(File.join(path_item, 'disco')).children.each { |disco_file| FileUtils.cp_r(disco_file, File.join(new_path, 'disco'), remove_destination: true) }
871
+ end
872
+
873
+ Pathname.new(path).children.each do |file|
874
+ if File.extname(file) == '.json'
875
+ puts file
876
+ if File.exist?(File.join(path_item, file))
877
+ FileUtils.cp_r(File.join(path_item, file), new_path)
878
+ end
879
+ end
880
+ end
881
+
882
+ end
883
+ end
884
+ end
885
+
886
+ # Setup Python Variables for DiTTo and DISCO
887
+ def self.setup_python_variables
888
+ pvars = {
889
+ python_version: '3.10',
890
+ miniconda_version: '4.12.0',
891
+ python_install_path: nil,
892
+ python_path: nil,
893
+ pip_path: nil,
894
+ ditto_path: nil,
895
+ gmt_path: nil
896
+ }
897
+
898
+ # get location
899
+ $LOAD_PATH.each do |path_item|
900
+ if path_item.to_s.end_with?('example_files')
901
+ # install python in cli gem's example_files/python_deps folder
902
+ # so it is accessible to all projects
903
+ pvars[:python_install_path] = File.join(path_item, 'python_deps')
904
+ pvars[:pip_path] = pvars[:python_install_path]
905
+ break
906
+ end
907
+ end
908
+ # look for config file and grab info
909
+ if File.exist? File.join(pvars[:python_install_path], 'python_config.json')
910
+ configs = JSON.parse(File.read(File.join(pvars[:python_install_path], 'python_config.json')), symbolize_names: true)
911
+ pvars[:python_path] = configs[:python_path]
912
+ pvars[:pip_path] = configs[:pip_path]
913
+ pvars[:ditto_path] = configs[:ditto_path]
914
+ pvars[:gmt_path] = configs[:gmt_path]
915
+ pvars[:disco_path] = configs[:disco_path]
916
+ end
917
+ return pvars
918
+ end
919
+
920
+ # Return UO python packages list from python_deps/dependencies.json
921
+ def self.get_python_deps
922
+ deps = []
923
+ the_path = ""
924
+ $LOAD_PATH.each do |path_item|
925
+ if path_item.to_s.end_with?('example_files')
926
+ # install python in cli gem's example_files/python_deps folder
927
+ # so it is accessible to all projects
928
+ the_path = File.join(path_item, 'python_deps')
929
+ break
930
+ end
931
+ end
932
+
933
+ if File.exist? File.join(the_path, 'dependencies.json')
934
+ deps = JSON.parse(File.read(File.join(the_path, 'dependencies.json')), symbolize_names: true)
935
+ end
936
+ return deps
937
+ end
938
+
939
+ # Check Python
940
+ def self.check_python(python_only: false)
941
+ results = { python: false, pvars: [], message: '', python_deps: false, result: false }
677
942
  puts 'Checking system.....'
943
+ pvars = setup_python_variables
944
+ results[:pvars] = pvars
678
945
 
679
- # platform agnostic
680
- stdout, stderr, status = Open3.capture3('python3 -V')
681
- if stderr && !stderr == ''
682
- # error
683
- results[:message] = "ERROR: #{stderr}"
946
+ # check vars
947
+ if pvars[:python_path].nil? || pvars[:pip_path].nil?
948
+ # need to install
949
+ results[:message] = 'Python paths have not yet been initialized with URBANopt.'
684
950
  puts results[:message]
685
951
  return results
686
952
  end
687
953
 
688
- # check version
689
- stdout.slice! 'Python3 '
690
- if stdout[0].to_i == 2 || (stdout[0].to_i == 3 && stdout[2].to_i < 7)
691
- # global python version is not 3.7+
692
- results[:message] = "ERROR: Python version must be at least 3.7. Found python with version #{stdout}."
954
+ # check python
955
+ stdout, stderr, status = Open3.capture3("#{pvars[:python_path]} -V")
956
+ if stderr.empty?
957
+ puts "...python found at #{pvars[:python_path]}"
958
+ else
959
+ results[:message] = "ERROR installing python: #{stderr}"
693
960
  puts results[:message]
694
961
  return results
695
- else
696
- puts "...Python >= 3.7 found (#{stdout.chomp})"
697
962
  end
698
963
 
699
964
  # check pip
700
- stdout, stderr, status = Open3.capture3('pip3 -V')
701
- if stderr && !stderr == ''
702
- # error
965
+ stdout, stderr, status = Open3.capture3("#{pvars[:pip_path]} -V")
966
+ if stderr.empty?
967
+ puts "...pip found at #{pvars[:pip_path]}"
968
+ else
703
969
  results[:message] = "ERROR finding pip: #{stderr}"
704
970
  puts results[:message]
705
971
  return results
706
- else
707
- puts '...pip found'
708
972
  end
709
973
 
710
- # all good
711
- puts 'System check done.'
974
+ # python and pip installed correctly
712
975
  results[:python] = true
976
+
977
+ # now check dependencies (if python_only is false)
978
+ unless python_only
979
+ deps = get_python_deps
980
+ puts "DEPENDENCIES RETRIEVED FROM FILE: #{deps}"
981
+ errors = []
982
+ deps.each do |dep|
983
+ #TODO: Update when there is a stable release for DISCO
984
+ if dep[:name].to_s.include? "disco"
985
+ stdout, stderr, status = Open3.capture3("#{pvars[:pip_path]} show NREL-disco")
986
+ else
987
+ stdout, stderr, status = Open3.capture3("#{pvars[:pip_path]} show #{dep[:name]}")
988
+ end
989
+ if stderr.empty?
990
+ # check versions
991
+ m = stdout.match /^Version: (\S{3,}$)/
992
+ err = true
993
+ if m and m.size > 1
994
+ if !dep[:version].nil? and dep[:version].to_s == m[1].to_s
995
+ puts "...#{dep[:name]} found with specified version #{dep[:version]}"
996
+ err = false
997
+ elsif dep[:version].nil?
998
+ err = false
999
+ puts "...#{dep[:name]} found (version #{m[1]})"
1000
+ end
1001
+ end
1002
+ if err
1003
+ results[:message] = "incorrect version found for #{dep[:name]}...expecting version #{dep[:version]}"
1004
+ puts results[:message]
1005
+ errors << stderr
1006
+ end
1007
+ else
1008
+ results[:message] = stderr
1009
+ puts results[:message]
1010
+ errors << stderr
1011
+ end
1012
+ end
1013
+ if errors.empty?
1014
+ results[:python_deps] = true
1015
+ end
1016
+ end
1017
+
1018
+ # all is good
1019
+ results[:result] = true
713
1020
  return results
714
1021
  end
715
1022
 
716
- def self.check_reader
717
- results = { reader: false, message: '' }
1023
+ # Install Python and Related Dependencies
1024
+ def self.install_python_dependencies
1025
+ pvars = setup_python_variables
1026
+
1027
+ # check if python and dependencies are already installed
1028
+ results = check_python
1029
+
1030
+ # install python if not installed
1031
+ if !results[:python]
1032
+
1033
+ # cd into script dir
1034
+ wd = Dir.getwd
1035
+ FileUtils.cd(pvars[:python_install_path])
1036
+ puts 'Installing python...'
1037
+ if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM).nil?
1038
+ # not windows
1039
+ script = File.join(pvars[:python_install_path], 'install_python.sh')
1040
+ the_command = "cd #{pvars[:python_install_path]}; #{script} #{pvars[:miniconda_version]} #{pvars[:python_version]} #{pvars[:python_install_path]}"
1041
+ stdout, stderr, status = Open3.capture3(the_command)
1042
+ if (stderr && !stderr == '') || (stdout && stdout.include?('Usage'))
1043
+ # error
1044
+ puts "ERROR installing python dependencies: #{stderr}, #{stdout}"
1045
+ return
1046
+ end
1047
+ # capture paths
1048
+ mac_path_base = File.join(pvars[:python_install_path], "Miniconda-#{pvars[:miniconda_version]}")
1049
+ pvars[:python_path] = File.join(mac_path_base, 'bin', 'python')
1050
+ pvars[:pip_path] = File.join(mac_path_base, 'bin', 'pip')
1051
+ pvars[:ditto_path] = File.join(mac_path_base, 'bin', 'ditto_reader_cli')
1052
+ pvars[:gmt_path] = File.join(mac_path_base, 'bin', 'uo_des')
1053
+ pvars[:disco_path] = File.join(mac_path_base, 'bin', 'disco')
1054
+ configs = {
1055
+ python_path: pvars[:python_path],
1056
+ pip_path: pvars[:pip_path],
1057
+ ditto_path: pvars[:ditto_path],
1058
+ gmt_path: pvars[:gmt_path],
1059
+ disco_path: pvars[:disco_path]
1060
+ }
1061
+ else
1062
+ # windows
1063
+ script = File.join(pvars[:python_install_path], 'install_python.ps1')
1064
+
1065
+ command_list = [
1066
+ 'powershell Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process',
1067
+ "powershell #{script} #{pvars[:miniconda_version]} #{pvars[:python_version]} #{pvars[:python_install_path]}",
1068
+ 'powershell $env:CONDA_DLL_SEARCH_MODIFICATION_ENABLE = 1'
1069
+ ]
1070
+
1071
+ command_list.each do |command|
1072
+ stdout, stderr, status = Open3.capture3(command)
1073
+ if !stderr.empty?
1074
+ puts "ERROR installing python dependencies: #{stderr}, #{stdout}"
1075
+ break
1076
+ end
1077
+ end
1078
+
1079
+ # capture paths
1080
+ windows_path_base = File.join(pvars[:python_install_path], "python-#{pvars[:python_version]}")
1081
+ pvars[:python_path] = File.join(windows_path_base, 'python.exe')
1082
+ pvars[:pip_path] = File.join(windows_path_base, 'Scripts', 'pip.exe')
1083
+ pvars[:ditto_path] = File.join(windows_path_base, 'Scripts', 'ditto_reader_cli.exe')
1084
+ pvars[:gmt_path] = File.join(windows_path_base, 'Scripts', 'uo_des.exe')
1085
+ pvars[:disco_path] = File.join(windows_path_base, 'Scripts', 'disco.exe')
1086
+
1087
+ configs = {
1088
+ python_path: pvars[:python_path],
1089
+ pip_path: pvars[:pip_path],
1090
+ ditto_path: pvars[:ditto_path],
1091
+ gmt_path: pvars[:gmt_path],
1092
+ disco_path: pvars[:disco_path]
1093
+ }
1094
+ end
718
1095
 
719
- puts 'Checking for urbanopt-ditto-reader...'
1096
+ # get back to wd
1097
+ FileUtils.cd(wd)
720
1098
 
721
- stdout, stderr, status = Open3.capture3('pip3 list')
722
- if stderr && !stderr == ''
723
- # error
724
- results[:message] = 'ERROR running pip list'
725
- puts results[:message]
726
- return results
1099
+ # write config file
1100
+ File.open(File.join(pvars[:python_install_path], 'python_config.json'), 'w') do |f|
1101
+ f.write(JSON.pretty_generate(configs))
1102
+ end
727
1103
  end
728
1104
 
729
- res = /^urbanopt-ditto-reader.*$/.match(stdout)
730
- if res
731
- # extract version
732
- version = /\d+.\d+.\d+/.match(res.to_s)
733
- path = res.to_s.split(' ')[-1]
734
- puts "...path: #{path}"
735
- if version
736
- results[:message] = "Found urbanopt-ditto-reader version #{version}"
737
- puts "...#{results[:message]}"
738
- results[:reader] = true
739
- puts "urbanopt-ditto-reader check done. \n\n"
740
- return results
741
- else
742
- results[:message] = 'urbanopt-ditto-reader version not found.'
743
- return results
1105
+ # install python dependencies if not installed
1106
+ if !results[:python_deps]
1107
+ deps = get_python_deps
1108
+ deps.each do |dep|
1109
+ puts "Installing #{dep[:name]}..."
1110
+ the_command = ""
1111
+ if dep[:version].nil?
1112
+ the_command = "#{pvars[:pip_path]} install #{dep[:name]}"
1113
+ else
1114
+ the_command = "#{pvars[:pip_path]} install #{dep[:name]}~=#{dep[:version]}"
1115
+ end
1116
+ # system(the_command)
1117
+ #puts "INSTALL COMMAND: #{the_command}"
1118
+ stdout, stderr, status = Open3.capture3(the_command)
1119
+ if stderr && !stderr == ''
1120
+ puts "Error installing: #{stderr}"
1121
+ end
744
1122
  end
1123
+ end
1124
+
1125
+ # double check python and dependencies have been installed now
1126
+ if !results[:result]
1127
+ # double check that everything has succeeded now
1128
+ results = check_python
1129
+ end
1130
+
1131
+ if results[:result]
1132
+ puts "Python and dependencies successfully installed in #{pvars[:python_install_path]}"
745
1133
  else
746
- # no ditto reader
747
- results[:message] = 'urbanopt-ditto-reader not found.'
748
- return results
1134
+ # errors occurred
1135
+ puts "Errors occurred when installing python and dependencies: #{results[:message]}"
749
1136
  end
750
1137
  end
751
1138
 
@@ -756,10 +1143,10 @@ module URBANopt
756
1143
  case @opthash.subopts[:overwrite]
757
1144
  when true
758
1145
  puts "\nOverwriting existing project folder: #{@opthash.subopts[:project_folder]}...\n\n"
759
- create_project_folder(@opthash.subopts[:project_folder], empty_folder = false, overwrite_project = true)
1146
+ create_project_folder(@opthash.subopts[:project_folder], empty_folder: false, overwrite_project: true)
760
1147
  when false
761
1148
  puts "\nCreating a new project folder...\n"
762
- create_project_folder(@opthash.subopts[:project_folder], empty_folder = false, overwrite_project = false)
1149
+ create_project_folder(@opthash.subopts[:project_folder], empty_folder: false, overwrite_project: false)
763
1150
  if @opthash.subopts[:floorspace] == false && @opthash.subopts[:create_bar] == true
764
1151
  puts "\nAn example FeatureFile is included: 'example_project.json'. You may place your own FeatureFile alongside the example."
765
1152
  elsif @opthash.subopts[:floorspace] == true && @opthash.subopts[:create_bar] == false
@@ -773,10 +1160,10 @@ module URBANopt
773
1160
  case @opthash.subopts[:overwrite]
774
1161
  when true
775
1162
  puts "\nOverwriting existing project folder: #{@opthash.subopts[:project_folder]} with an empty folder...\n\n"
776
- create_project_folder(@opthash.subopts[:project_folder], empty_folder = true, overwrite_project = true)
1163
+ create_project_folder(@opthash.subopts[:project_folder], empty_folder: true, overwrite_project: true)
777
1164
  when false
778
1165
  puts "\nCreating a new empty project folder...\n"
779
- create_project_folder(@opthash.subopts[:project_folder], empty_folder = true, overwrite_project = false)
1166
+ create_project_folder(@opthash.subopts[:project_folder], empty_folder: true, overwrite_project: false)
780
1167
  end
781
1168
  puts "\nAdd your FeatureFile in the Project directory you just created."
782
1169
  puts 'Add your weather data files in the Weather folder. They may be downloaded from energyplus.net/weather for free'
@@ -798,11 +1185,34 @@ module URBANopt
798
1185
  end
799
1186
  end
800
1187
 
801
- # Create REopt ScenarioFile from existing
802
- if @opthash.command == 'create' && @opthash.subopts[:reopt_scenario_file]
803
- puts "\nCreating ScenarioFile with REopt functionality, extending from #{@opthash.subopts[:reopt_scenario_file]}..."
804
- create_reopt_scenario_file(@opthash.subopts[:reopt_scenario_file])
805
- puts "\nDone"
1188
+ # Create REopt ScenarioFile from existing
1189
+ if @opthash.command == 'create' && @opthash.subopts[:reopt_scenario_file]
1190
+ puts "\nCreating ScenarioFile with REopt functionality, extending from #{@opthash.subopts[:reopt_scenario_file]}..."
1191
+ create_reopt_scenario_file(@opthash.subopts[:reopt_scenario_file])
1192
+ puts "\nDone"
1193
+ end
1194
+
1195
+ # Graceful error if no flag is provided when using `create` command
1196
+ if @opthash.command == 'create' &&
1197
+ @opthash.subopts[:scenario_file].nil? &&
1198
+ @opthash.subopts[:reopt_scenario_file].nil? &&
1199
+ @opthash.subopts[:project_folder].nil?
1200
+ abort("\nNo options provided to the `create` command. Did you forget the `-p` flag? See `uo create --help` for all options\n")
1201
+ end
1202
+
1203
+ # Update existing URBANopt Project files
1204
+ if @opthash.command == 'update'
1205
+ puts "\nUpdating files in URBANopt project #{@opthash.subopts[:existing_project_folder]} and storing them in updated project folder at #{@opthash.subopts[:new_project_directory]}..."
1206
+ update_project(@opthash.subopts[:existing_project_folder].to_s, @opthash.subopts[:new_project_directory].to_s)
1207
+ puts "\nProject files updated to URBANopt CLI Version #{URBANopt::CLI::VERSION}...double check your runner.conf file as well as any other files you may have previously manually configured."
1208
+ puts "\nDone"
1209
+ end
1210
+
1211
+ # Install python and other dependencies
1212
+ if @opthash.command == 'install_python'
1213
+ puts "\nInstalling python and dependencies"
1214
+ install_python_dependencies
1215
+ puts "\nDone\n"
806
1216
  end
807
1217
 
808
1218
  # Run simulations
@@ -812,13 +1222,13 @@ module URBANopt
812
1222
  if ENV['UO_NUM_PARALLEL'] || @opthash.subopts[:num_parallel]
813
1223
  runner_file_path = File.join(@root_dir, 'runner.conf')
814
1224
  runner_conf_hash = JSON.parse(File.read(runner_file_path))
815
- if ENV['UO_NUM_PARALLEL']
816
- runner_conf_hash['num_parallel'] = ENV['UO_NUM_PARALLEL'].to_i
1225
+ if @opthash.subopts[:num_parallel]
1226
+ runner_conf_hash['num_parallel'] = @opthash.subopts[:num_parallel]
817
1227
  File.open(runner_file_path, 'w+') do |f|
818
1228
  f << runner_conf_hash.to_json
819
1229
  end
820
- elsif @opthash.subopts[:num_parallel]
821
- runner_conf_hash['num_parallel'] = @opthash.subopts[:num_parallel].to_i
1230
+ elsif ENV['UO_NUM_PARALLEL']
1231
+ runner_conf_hash['num_parallel'] = ENV['UO_NUM_PARALLEL'].to_i
822
1232
  File.open(runner_file_path, 'w+') do |f|
823
1233
  f << runner_conf_hash.to_json
824
1234
  end
@@ -842,18 +1252,10 @@ module URBANopt
842
1252
  res = check_python
843
1253
  if res[:python] == false
844
1254
  puts "\nPython error: #{res[:message]}"
845
- abort("\nYou must install Python 3.7 or above and pip to use this workflow \n")
846
- end
847
-
848
- # then check if ditto_reader is installed
849
- res = check_reader
850
- if res[:reader] == false
851
- puts "\nURBANopt ditto reader error: #{res[:message]}"
852
- abort("\nYou must install urbanopt-ditto-reader to use this workflow: pip install urbanopt-ditto-reader \n")
1255
+ abort("\nPython dependencies are needed to run this workflow. Install with the CLI command: uo install_python \n")
853
1256
  end
854
1257
 
855
1258
  # If a config file is supplied, use the data specified there.
856
- # absolute paths or paths relative to the location of the config file
857
1259
  if @opthash.subopts[:config]
858
1260
 
859
1261
  opendss_config = JSON.parse(File.read(File.expand_path(@opthash.subopts[:config])), symbolize_names: true)
@@ -868,7 +1270,6 @@ module URBANopt
868
1270
 
869
1271
  puts "Scenario path: #{scenario_path}"
870
1272
 
871
- #config_root_dir = File.dirname(File.expand_path(config_scenario_file))
872
1273
  config_root_dir = config_path
873
1274
  run_dir = File.join(config_root_dir, 'run', config_scenario_name.downcase)
874
1275
  featurefile = Pathname.new(opendss_config[:urbanopt_geojson_file])
@@ -878,9 +1279,6 @@ module URBANopt
878
1279
 
879
1280
  puts "Run Dir: #{run_dir}"
880
1281
 
881
- # NOTE: this is "fixed" from the CLI perspective.
882
- # but Ditto reader CLI can't handle relative paths correctly so use absolute paths in the config file
883
-
884
1282
  elsif @opthash.subopts[:scenario] && @opthash.subopts[:feature]
885
1283
  # Otherwise use the user-supplied scenario & feature files
886
1284
  run_dir = File.join(@root_dir, 'run', @scenario_name.downcase)
@@ -905,9 +1303,7 @@ module URBANopt
905
1303
  abort("ERROR: URBANopt simulations are required before using opendss. Please run and process simulations, then try again.\n")
906
1304
  end
907
1305
 
908
- # We're calling the python cli that gets installed when the user installs ditto-reader.
909
- # If ditto-reader is installed into a venv (recommended), that venv must be activated when this command is called.
910
- ditto_cli_root = 'ditto_reader_cli run-opendss '
1306
+ ditto_cli_root = "#{res[:pvars][:ditto_path]} run-opendss "
911
1307
  if @opthash.subopts[:config]
912
1308
  ditto_cli_addition = "--config #{@opthash.subopts[:config]}"
913
1309
  elsif @opthash.subopts[:scenario] && @opthash.subopts[:feature]
@@ -933,6 +1329,9 @@ module URBANopt
933
1329
  if @opthash.subopts[:reopt]
934
1330
  ditto_cli_addition += ' --reopt'
935
1331
  end
1332
+ if @opthash.subopts[:rnm]
1333
+ ditto_cli_addition += ' --rnm'
1334
+ end
936
1335
  if @opthash.subopts[:upgrade]
937
1336
  ditto_cli_addition += ' --upgrade'
938
1337
  end
@@ -940,7 +1339,7 @@ module URBANopt
940
1339
  abort("\nCommand must include ScenarioFile & FeatureFile, or a config file that specifies both. Please try again")
941
1340
  end
942
1341
  begin
943
- puts "!!DITTO COMMAND: #{ditto_cli_root + ditto_cli_addition}"
1342
+ puts "COMMAND: #{ditto_cli_root + ditto_cli_addition}"
944
1343
  system(ditto_cli_root + ditto_cli_addition)
945
1344
  rescue FileNotFoundError
946
1345
  abort("\nMust post-process results before running OpenDSS. We recommend 'process --default'." \
@@ -948,6 +1347,82 @@ module URBANopt
948
1347
  end
949
1348
  end
950
1349
 
1350
+ # Run DISCO Simulation
1351
+ if @opthash.command == 'disco'
1352
+
1353
+ # first check python and python dependencies
1354
+ res = check_python
1355
+ if res[:result] == false
1356
+ puts "\nPython error: #{res[:message]}"
1357
+ abort("\nPython dependencies are needed to run this workflow. Install with the CLI command: uo install_python \n")
1358
+ else
1359
+ disco_path = res[:pvars][:disco_path]
1360
+ end
1361
+
1362
+ # disco folder
1363
+ disco_folder = File.join(@root_dir, 'disco')
1364
+
1365
+ # run folder
1366
+ run_folder = File.join(@root_dir, 'run', @scenario_name.downcase)
1367
+
1368
+ # check of opendss models are created
1369
+ opendss_file = File.join(run_folder, 'opendss/dss_files/Master.dss')
1370
+ if !File.exist?(opendss_file)
1371
+ abort("\nYou must run the OpenDSS analysis before running DISCO. Refer to 'opendss --help' for details on how to run th OpenDSS analysis.")
1372
+ end
1373
+
1374
+ if @opthash.subopts[:technical_catalog]
1375
+ # users can specify their technical catalogue name, placed in the disco folder
1376
+ technical_catalog = @opthash.subopts[:technical_catalog]
1377
+ else
1378
+ technical_catalog = 'technical_catalog.json'
1379
+ end
1380
+
1381
+ # set arguments in config hash
1382
+ config_hash = JSON.parse(File.read(File.join(disco_folder, 'config.json')), symbolize_names: true)
1383
+ config_hash[:upgrade_cost_database] = File.join(disco_folder, @opthash.subopts[:cost_database]) # Uses default cost database if not specified
1384
+ if technical_catalog
1385
+ config_hash[:thermal_upgrade_params][:read_external_catalog] = true
1386
+ config_hash[:thermal_upgrade_params][:external_catalog] = File.join(disco_folder, technical_catalog)
1387
+ end
1388
+ config_hash[:jobs][0][:name] = @scenario_name
1389
+ config_hash[:jobs][0][:opendss_model_file] = opendss_file
1390
+
1391
+ # save config file in run folder
1392
+ File.open(File.join(run_folder, 'config.json'), 'w') { |f| f.write(JSON.pretty_generate(config_hash)) }
1393
+
1394
+ # call disco
1395
+ FileUtils.cd(run_folder) do
1396
+ if (/cygwin|mswin|mingw|bccwin|wince|emx/ =~ RUBY_PLATFORM).nil?
1397
+ # not windows
1398
+ if Dir.exist?(File.join(run_folder, 'disco'))
1399
+ # if disco results folder exists overwrite folder
1400
+ commands = ["#{disco_path} upgrade-cost-analysis run config.json -o disco --console-log-level=warn --force"]
1401
+ else
1402
+ commands = ["#{disco_path} upgrade-cost-analysis run config.json -o disco --console-log-level=warn"]
1403
+ end
1404
+ else
1405
+ # windows
1406
+ if Dir.exist?(File.join(run_folder, 'disco'))
1407
+ # if disco results folder exists overwrite folder)
1408
+ commands = ['powershell $env:CONDA_DLL_SEARCH_MODIFICATION_ENABLE = 1', "#{disco_path} upgrade-cost-analysis run config.json -o disco --console-log-level=warn --force"]
1409
+ else
1410
+ commands = ['powershell $env:CONDA_DLL_SEARCH_MODIFICATION_ENABLE = 1', "#{disco_path} upgrade-cost-analysis run config.json -o disco --console-log-level=warn"]
1411
+ end
1412
+ end
1413
+ puts 'Running DISCO...'
1414
+ commands.each do |command|
1415
+ # TODO: This will be updated so stderr only reports error/warnings at DISCO level
1416
+ stdout, stderr, status = Open3.capture3(command)
1417
+ if !stderr.empty?
1418
+ puts "ERROR running DISCO: #{stderr}"
1419
+ end
1420
+ end
1421
+ puts "Refer to detailed log file #{File.join(run_folder,'disco','run_upgrade_cost_analysis.log')} for more information on the run."
1422
+ puts "Refer to the output summary file #{File.join(run_folder,'disco','output_summary.json')} for a summary of the results."
1423
+ end
1424
+ end
1425
+
951
1426
  # Run RNM Simulation
952
1427
  if @opthash.command == 'rnm'
953
1428
 
@@ -984,7 +1459,7 @@ module URBANopt
984
1459
 
985
1460
  # Post-process the scenario
986
1461
  if @opthash.command == 'process'
987
- if @opthash.subopts[:default] == false && @opthash.subopts[:opendss] == false && @opthash.subopts[:reopt_scenario] == false && @opthash.subopts[:reopt_feature] == false
1462
+ if @opthash.subopts[:default] == false && @opthash.subopts[:opendss] == false && @opthash.subopts[:reopt_scenario] == false && @opthash.subopts[:reopt_feature] == false && @opthash.subopts[:disco] == false
988
1463
  abort("\nERROR: No valid process type entered. Must enter a valid process type\n")
989
1464
  end
990
1465
 
@@ -997,7 +1472,7 @@ module URBANopt
997
1472
 
998
1473
  default_post_processor = URBANopt::Scenario::ScenarioDefaultPostProcessor.new(run_func)
999
1474
  scenario_report = default_post_processor.run
1000
- scenario_report.save(file_name = 'default_scenario_report', save_feature_reports = false)
1475
+ scenario_report.save(file_name = 'default_scenario_report', save_feature_reports: false)
1001
1476
  scenario_report.feature_reports.each(&:save)
1002
1477
 
1003
1478
  if @opthash.subopts[:with_database] == true
@@ -1006,7 +1481,7 @@ module URBANopt
1006
1481
 
1007
1482
  if @opthash.subopts[:default] == true
1008
1483
  puts "\nDone\n"
1009
- results << { "process_type": 'default', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1484
+ results << { process_type: 'default', status: 'Complete', timestamp: Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1010
1485
  elsif @opthash.subopts[:opendss] == true
1011
1486
  puts "\nPost-processing OpenDSS results\n"
1012
1487
  opendss_folder = File.join(@root_dir, 'run', @scenario_name.downcase, 'opendss')
@@ -1018,14 +1493,30 @@ module URBANopt
1018
1493
  )
1019
1494
  opendss_post_processor.run
1020
1495
  puts "\nDone\n"
1021
- results << { "process_type": 'opendss', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1496
+ results << { process_type: 'opendss', status: 'Complete', timestamp: Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1022
1497
  else
1023
- results << { "process_type": 'opendss', "status": 'failed', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1498
+ results << { process_type: 'opendss', status: 'failed', timestamp: Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1024
1499
  abort("\nNo OpenDSS results available in folder '#{opendss_folder}'\n")
1025
1500
  end
1501
+ elsif @opthash.subopts[:disco] == true
1502
+ puts "\nPost-processing DISCO results\n"
1503
+ disco_folder = File.join(@root_dir, 'run', @scenario_name.downcase, 'disco')
1504
+ if File.directory?(disco_folder)
1505
+ disco_folder_name = File.basename(disco_folder)
1506
+ disco_post_processor = URBANopt::Scenario::DISCOPostProcessor.new(
1507
+ scenario_report,
1508
+ disco_results_dir_name = disco_folder_name
1509
+ )
1510
+ disco_post_processor.run
1511
+ puts "\nDone\n"
1512
+ results << { process_type: 'disco', status: 'Complete', timestamp: Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1513
+ else
1514
+ results << { process_type: 'disco', status: 'failed', timestamp: Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1515
+ abort("\nNo DISCO results available in folder '#{opendss_folder}'\n")
1516
+ end
1026
1517
  elsif (@opthash.subopts[:reopt_scenario] == true) || (@opthash.subopts[:reopt_feature] == true)
1027
1518
  # Ensure reopt default files are prepared
1028
- #create_reopt_files(@opthash.subopts[:scenario])
1519
+ # create_reopt_files(@opthash.subopts[:scenario])
1029
1520
 
1030
1521
  scenario_base = default_post_processor.scenario_base
1031
1522
 
@@ -1059,7 +1550,7 @@ module URBANopt
1059
1550
  run_resilience: @opthash.subopts[:reopt_resilience],
1060
1551
  community_photovoltaic: community_photovoltaic
1061
1552
  )
1062
- results << { "process_type": 'reopt_scenario', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1553
+ results << { process_type: 'reopt_scenario', status: 'Complete', timestamp: Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1063
1554
  puts "\nDone\n"
1064
1555
  elsif @opthash.subopts[:reopt_feature] == true
1065
1556
  puts "\nPost-processing each building individually with REopt\n"
@@ -1080,7 +1571,7 @@ module URBANopt
1080
1571
  keep_existing_output: @opthash.subopts[:reopt_keep_existing],
1081
1572
  groundmount_photovoltaic: groundmount_photovoltaic
1082
1573
  )
1083
- results << { "process_type": 'reopt_feature', "status": 'Complete', "timestamp": Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1574
+ results << { process_type: 'reopt_feature', status: 'Complete', timestamp: Time.now.strftime('%Y-%m-%dT%k:%M:%S.%L') }
1084
1575
  puts "\nDone\n"
1085
1576
  end
1086
1577
  end
@@ -1232,9 +1723,9 @@ module URBANopt
1232
1723
  if feature_eui_value > validation_params['EUI'][@opthash.subopts[:units]][building_type]['max']
1233
1724
  puts "\nFeature #{File.basename(feature_path)} EUI of #{feature_eui_value.round(2)} #{unit_value} is greater than the validation maximum."
1234
1725
  elsif feature_eui_value < validation_params['EUI'][@opthash.subopts[:units]][building_type]['min']
1235
- puts "\nFeature #{File.basename(feature_path)} EUI of #{feature_eui_value.round(2)} #{unit_value} is less than the validation minimum."
1726
+ puts "\nFeature #{File.basename(feature_path)} (#{building_type}) EUI of #{feature_eui_value.round(2)} #{unit_value} is less than the validation minimum."
1236
1727
  else
1237
- puts "\nFeature #{File.basename(feature_path)} EUI of #{feature_eui_value.round(2)} #{unit_value} is within bounds set by #{validation_file_name}."
1728
+ puts "\nFeature #{File.basename(feature_path)} (#{building_type}) EUI of #{feature_eui_value.round(2)} #{unit_value} is within bounds set by #{validation_file_name}."
1238
1729
  end
1239
1730
  end
1240
1731
  end
@@ -1242,9 +1733,15 @@ module URBANopt
1242
1733
  end
1243
1734
 
1244
1735
  if @opthash.command == 'des_params'
1245
- # We're calling the python cli that gets installed when the user pip installs geojson-modelica-reader.
1246
- # If geojson-modelica-reader is installed into a venv (recommended), that venv must be activated when this command is called.
1247
- des_cli_root = 'uo_des build-sys-param'
1736
+
1737
+ # first check python
1738
+ res = check_python
1739
+ if res[:python] == false
1740
+ puts "\nPython error: #{res[:message]}"
1741
+ abort("\nPython dependencies are needed to run this workflow. Install with the CLI command: uo install_python \n")
1742
+ end
1743
+
1744
+ des_cli_root = "#{res[:pvars][:gmt_path]} build-sys-param"
1248
1745
  if @opthash.subopts[:sys_param_file]
1249
1746
  des_cli_addition = " #{@opthash.subopts[:sys_param_file]}"
1250
1747
  if @opthash.subopts[:scenario]
@@ -1267,9 +1764,15 @@ module URBANopt
1267
1764
  end
1268
1765
 
1269
1766
  if @opthash.command == 'des_create'
1270
- # We're calling the python cli that gets installed when the user pip installs geojson-modelica-reader.
1271
- # If geojson-modelica-reader is installed into a venv (recommended), that venv must be activated when this command is called.
1272
- des_cli_root = 'uo_des create-model'
1767
+
1768
+ # first check python
1769
+ res = check_python
1770
+ if res[:python] == false
1771
+ puts "\nPython error: #{res[:message]}"
1772
+ abort("\nPython dependencies are needed to run this workflow. Install with the CLI command: uo install_python \n")
1773
+ end
1774
+
1775
+ des_cli_root = "#{res[:pvars][:gmt_path]} create-model"
1273
1776
  if @opthash.subopts[:sys_param]
1274
1777
  des_cli_addition = " #{@opthash.subopts[:sys_param]}"
1275
1778
  if @opthash.subopts[:feature]
@@ -1292,9 +1795,15 @@ module URBANopt
1292
1795
  end
1293
1796
 
1294
1797
  if @opthash.command == 'des_run'
1295
- # We're calling the python cli that gets installed when the user pip installs geojson-modelica-reader.
1296
- # If geojson-modelica-reader is installed into a venv (recommended), that venv must be activated when this command is called.
1297
- des_cli_root = 'uo_des run-model'
1798
+
1799
+ # first check python
1800
+ res = check_python
1801
+ if res[:python] == false
1802
+ puts "\nPython error: #{res[:message]}"
1803
+ abort("\nPython dependencies are needed to run this workflow. Install with the CLI command: uo install_python \n")
1804
+ end
1805
+
1806
+ des_cli_root = "#{res[:pvars][:gmt_path]} run-model"
1298
1807
  if @opthash.subopts[:model]
1299
1808
  des_cli_addition = " #{File.expand_path(@opthash.subopts[:model])}"
1300
1809
  else