openstudio-common-measures 0.3.2 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (434) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +15 -0
  3. data/Jenkinsfile +2 -1
  4. data/LICENSE.md +1 -1
  5. data/doc_templates/LICENSE.md +1 -1
  6. data/doc_templates/copyright_erb.txt +1 -1
  7. data/doc_templates/copyright_js.txt +1 -1
  8. data/doc_templates/copyright_ruby.txt +1 -1
  9. data/lib/measures/AddCostPerAreaToConstruction/LICENSE.md +1 -1
  10. data/lib/measures/AddCostPerAreaToConstruction/measure.rb +1 -1
  11. data/lib/measures/AddCostPerAreaToConstruction/measure.xml +8 -7
  12. data/lib/measures/AddCostPerFloorAreaToBuilding/LICENSE.md +1 -1
  13. data/lib/measures/AddCostPerFloorAreaToBuilding/measure.rb +1 -1
  14. data/lib/measures/AddCostPerFloorAreaToBuilding/measure.xml +8 -7
  15. data/lib/measures/AddCostPerFloorAreaToElectricEquipment/LICENSE.md +1 -1
  16. data/lib/measures/AddCostPerFloorAreaToElectricEquipment/measure.rb +1 -1
  17. data/lib/measures/AddCostPerFloorAreaToElectricEquipment/measure.xml +8 -7
  18. data/lib/measures/AddCostPerFloorAreaToLights/LICENSE.md +1 -1
  19. data/lib/measures/AddCostPerFloorAreaToLights/measure.rb +1 -1
  20. data/lib/measures/AddCostPerFloorAreaToLights/measure.xml +8 -7
  21. data/lib/measures/AddCostPerFloorAreaUnusedToLights/LICENSE.md +1 -1
  22. data/lib/measures/AddCostPerFloorAreaUnusedToLights/measure.rb +1 -1
  23. data/lib/measures/AddCostPerFloorAreaUnusedToLights/measure.xml +8 -7
  24. data/lib/measures/AddCostToSupplySideHVACComponentByAirLoop/LICENSE.md +1 -1
  25. data/lib/measures/AddCostToSupplySideHVACComponentByAirLoop/measure.rb +1 -1
  26. data/lib/measures/AddCostToSupplySideHVACComponentByAirLoop/measure.xml +9 -8
  27. data/lib/measures/AddCostperAreatoUnusedConstruction/LICENSE.md +1 -1
  28. data/lib/measures/AddCostperAreatoUnusedConstruction/measure.rb +1 -1
  29. data/lib/measures/AddCostperAreatoUnusedConstruction/measure.xml +8 -7
  30. data/lib/measures/AddExteriorLights/LICENSE.md +1 -1
  31. data/lib/measures/AddExteriorLights/measure.rb +1 -1
  32. data/lib/measures/AddExteriorLights/measure.xml +8 -7
  33. data/lib/measures/AddMeter/LICENSE.md +1 -1
  34. data/lib/measures/AddMeter/measure.rb +1 -1
  35. data/lib/measures/AddMeter/measure.xml +8 -7
  36. data/lib/measures/AddOutputDiagnostics/LICENSE.md +1 -1
  37. data/lib/measures/AddOutputDiagnostics/measure.rb +1 -1
  38. data/lib/measures/AddOutputDiagnostics/measure.xml +8 -7
  39. data/lib/measures/AddOutputVariable/LICENSE.md +1 -1
  40. data/lib/measures/AddOutputVariable/measure.rb +1 -1
  41. data/lib/measures/AddOutputVariable/measure.xml +8 -7
  42. data/lib/measures/AddSimplePvToShadingSurfacesByType/LICENSE.md +1 -1
  43. data/lib/measures/AddSimplePvToShadingSurfacesByType/measure.rb +1 -1
  44. data/lib/measures/AddSimplePvToShadingSurfacesByType/measure.xml +8 -7
  45. data/lib/measures/AdjustSystemEfficiencies/LICENSE.md +1 -1
  46. data/lib/measures/AdjustSystemEfficiencies/measure.rb +1 -1
  47. data/lib/measures/AdjustSystemEfficiencies/measure.xml +7 -6
  48. data/lib/measures/AdjustThermostatSetpointsByDegrees/LICENSE.md +1 -1
  49. data/lib/measures/AdjustThermostatSetpointsByDegrees/measure.rb +1 -1
  50. data/lib/measures/AdjustThermostatSetpointsByDegrees/measure.xml +8 -7
  51. data/lib/measures/ChangeBuildingLocation/LICENSE.md +1 -1
  52. data/lib/measures/ChangeBuildingLocation/measure.rb +3 -3
  53. data/lib/measures/ChangeBuildingLocation/measure.xml +17 -17
  54. data/lib/measures/ChangeBuildingLocation/resources/epw.rb +1 -1
  55. data/lib/measures/ChangeBuildingLocation/resources/stat_file.rb +1 -1
  56. data/lib/measures/EnableIdealAirLoadsForAllZones/LICENSE.md +1 -1
  57. data/lib/measures/EnableIdealAirLoadsForAllZones/measure.rb +1 -1
  58. data/lib/measures/EnableIdealAirLoadsForAllZones/measure.xml +9 -8
  59. data/lib/measures/ExportScheduleCSV/LICENSE.md +1 -1
  60. data/lib/measures/ExportScheduleCSV/measure.rb +1 -1
  61. data/lib/measures/ExportScheduleCSV/measure.xml +11 -11
  62. data/lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/LICENSE.md +1 -1
  63. data/lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/measure.rb +1 -1
  64. data/lib/measures/ImportEnvelopeAndInternalLoadsFromIdf/measure.xml +5 -5
  65. data/lib/measures/MeterFlodPlot/LICENSE.md +1 -1
  66. data/lib/measures/MeterFlodPlot/measure.rb +1 -1
  67. data/lib/measures/MeterFlodPlot/measure.xml +11 -11
  68. data/lib/measures/ModifyEnergyPlusCoilCoolingDXSingleSpeedObjects/LICENSE.md +1 -1
  69. data/lib/measures/ModifyEnergyPlusCoilCoolingDXSingleSpeedObjects/measure.rb +1 -1
  70. data/lib/measures/ModifyEnergyPlusCoilCoolingDXSingleSpeedObjects/measure.xml +8 -7
  71. data/lib/measures/ModifyEnergyPlusFanVariableVolumeObjects/LICENSE.md +1 -1
  72. data/lib/measures/ModifyEnergyPlusFanVariableVolumeObjects/measure.rb +1 -1
  73. data/lib/measures/ModifyEnergyPlusFanVariableVolumeObjects/measure.xml +8 -7
  74. data/lib/measures/PredictedMeanVote/LICENSE.md +1 -1
  75. data/lib/measures/PredictedMeanVote/measure.rb +1 -1
  76. data/lib/measures/PredictedMeanVote/measure.xml +14 -13
  77. data/lib/measures/RemoveInternalLoadsDirectlyAssignedToSpaces/LICENSE.md +1 -1
  78. data/lib/measures/RemoveInternalLoadsDirectlyAssignedToSpaces/measure.rb +1 -1
  79. data/lib/measures/RemoveInternalLoadsDirectlyAssignedToSpaces/measure.xml +9 -8
  80. data/lib/measures/RemoveUnusedDefaultProfiles/LICENSE.md +1 -1
  81. data/lib/measures/RemoveUnusedDefaultProfiles/measure.rb +1 -1
  82. data/lib/measures/RemoveUnusedDefaultProfiles/measure.xml +9 -8
  83. data/lib/measures/ReplaceExteriorWindowConstruction/LICENSE.md +1 -1
  84. data/lib/measures/ReplaceExteriorWindowConstruction/measure.rb +1 -1
  85. data/lib/measures/ReplaceExteriorWindowConstruction/measure.xml +11 -10
  86. data/lib/measures/ReplaceThermostatSchedules/LICENSE.md +1 -1
  87. data/lib/measures/ReplaceThermostatSchedules/measure.rb +1 -1
  88. data/lib/measures/ReplaceThermostatSchedules/measure.xml +12 -11
  89. data/lib/measures/ReportModelChanges/LICENSE.md +1 -1
  90. data/lib/measures/ReportModelChanges/measure.rb +1 -1
  91. data/lib/measures/ReportModelChanges/measure.xml +5 -5
  92. data/lib/measures/RunPeriod/LICENSE.md +1 -1
  93. data/lib/measures/RunPeriod/measure.rb +1 -1
  94. data/lib/measures/RunPeriod/measure.xml +19 -18
  95. data/lib/measures/RunPeriodMultiple/LICENSE.md +1 -1
  96. data/lib/measures/RunPeriodMultiple/measure.rb +1 -1
  97. data/lib/measures/RunPeriodMultiple/measure.xml +4 -4
  98. data/lib/measures/ServerDirectoryCleanup/LICENSE.md +1 -1
  99. data/lib/measures/ServerDirectoryCleanup/measure.rb +1 -1
  100. data/lib/measures/ServerDirectoryCleanup/measure.xml +16 -16
  101. data/lib/measures/SetCOPforSingleSpeedDXCoolingUnits/LICENSE.md +1 -1
  102. data/lib/measures/SetCOPforSingleSpeedDXCoolingUnits/measure.rb +1 -1
  103. data/lib/measures/SetCOPforSingleSpeedDXCoolingUnits/measure.xml +10 -9
  104. data/lib/measures/SetCOPforTwoSpeedDXCoolingUnits/LICENSE.md +1 -1
  105. data/lib/measures/SetCOPforTwoSpeedDXCoolingUnits/measure.rb +1 -1
  106. data/lib/measures/SetCOPforTwoSpeedDXCoolingUnits/measure.xml +10 -9
  107. data/lib/measures/SetEnergyPlusInfiltrationFlowRatePerFloorArea/LICENSE.md +1 -1
  108. data/lib/measures/SetEnergyPlusInfiltrationFlowRatePerFloorArea/measure.rb +1 -1
  109. data/lib/measures/SetEnergyPlusInfiltrationFlowRatePerFloorArea/measure.xml +8 -7
  110. data/lib/measures/SetEnergyPlusLightObjectsLPD/LICENSE.md +1 -1
  111. data/lib/measures/SetEnergyPlusLightObjectsLPD/measure.rb +1 -1
  112. data/lib/measures/SetEnergyPlusLightObjectsLPD/measure.xml +8 -7
  113. data/lib/measures/SetEnergyPlusMinimumOutdoorAirFlowRate/LICENSE.md +1 -1
  114. data/lib/measures/SetEnergyPlusMinimumOutdoorAirFlowRate/measure.rb +1 -1
  115. data/lib/measures/SetEnergyPlusMinimumOutdoorAirFlowRate/measure.xml +8 -7
  116. data/lib/measures/SetGasBurnerEfficiency/LICENSE.md +1 -1
  117. data/lib/measures/SetGasBurnerEfficiency/measure.rb +1 -1
  118. data/lib/measures/SetGasBurnerEfficiency/measure.xml +10 -9
  119. data/lib/measures/SetLifecycleCostParameters/LICENSE.md +1 -1
  120. data/lib/measures/SetLifecycleCostParameters/measure.rb +1 -1
  121. data/lib/measures/SetLifecycleCostParameters/measure.xml +8 -7
  122. data/lib/measures/SetLightingLoadsByLPD/LICENSE.md +1 -1
  123. data/lib/measures/SetLightingLoadsByLPD/measure.rb +1 -1
  124. data/lib/measures/SetLightingLoadsByLPD/measure.xml +10 -9
  125. data/lib/measures/SetSpaceInfiltrationByExteriorSurfaceArea/LICENSE.md +1 -1
  126. data/lib/measures/SetSpaceInfiltrationByExteriorSurfaceArea/measure.rb +1 -1
  127. data/lib/measures/SetSpaceInfiltrationByExteriorSurfaceArea/measure.xml +20 -19
  128. data/lib/measures/SetThermostatSchedules/LICENSE.md +1 -1
  129. data/lib/measures/SetThermostatSchedules/measure.rb +1 -1
  130. data/lib/measures/SetThermostatSchedules/measure.xml +12 -11
  131. data/lib/measures/ShiftScheduleProfileTime/LICENSE.md +1 -1
  132. data/lib/measures/ShiftScheduleProfileTime/measure.rb +1 -1
  133. data/lib/measures/ShiftScheduleProfileTime/measure.xml +10 -9
  134. data/lib/measures/SwapLightsDefinition/LICENSE.md +1 -1
  135. data/lib/measures/SwapLightsDefinition/measure.rb +1 -1
  136. data/lib/measures/SwapLightsDefinition/measure.xml +10 -9
  137. data/lib/measures/UnmetLoadHoursTroubleshooting/LICENSE.md +1 -1
  138. data/lib/measures/UnmetLoadHoursTroubleshooting/measure.rb +1 -1
  139. data/lib/measures/UnmetLoadHoursTroubleshooting/measure.xml +11 -11
  140. data/lib/measures/VentilationQAQC/LICENSE.md +1 -1
  141. data/lib/measures/VentilationQAQC/measure.rb +1 -1
  142. data/lib/measures/VentilationQAQC/measure.xml +17 -17
  143. data/lib/measures/ZoneReport/LICENSE.md +1 -1
  144. data/lib/measures/ZoneReport/measure.rb +1 -1
  145. data/lib/measures/ZoneReport/measure.xml +11 -11
  146. data/lib/measures/add_ems_to_control_ev_charging/LICENSE.MD.txt +1 -1
  147. data/lib/measures/add_ems_to_control_ev_charging/LICENSE.md +1 -1
  148. data/lib/measures/add_ems_to_control_ev_charging/measure.rb +2 -1
  149. data/lib/measures/add_ems_to_control_ev_charging/measure.xml +14 -10
  150. data/lib/measures/add_ev_load/LICENSE.MD.txt +1 -1
  151. data/lib/measures/add_ev_load/LICENSE.md +1 -1
  152. data/lib/measures/add_ev_load/measure.rb +5 -2
  153. data/lib/measures/add_ev_load/measure.xml +210 -15
  154. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/PSN_BuildingKey.csv → PSN_BuildingKey.csv} +0 -0
  155. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/PSN_BuildingKey_v2.csv → PSN_BuildingKey_v2.csv} +0 -0
  156. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow1_flex1.csv → chg1_dow1_flex1.csv} +0 -0
  157. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow1_flex2.csv → chg1_dow1_flex2.csv} +0 -0
  158. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow1_flex3.csv → chg1_dow1_flex3.csv} +0 -0
  159. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow2_flex1.csv → chg1_dow2_flex1.csv} +0 -0
  160. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow2_flex2.csv → chg1_dow2_flex2.csv} +0 -0
  161. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow2_flex3.csv → chg1_dow2_flex3.csv} +0 -0
  162. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow3_flex1.csv → chg1_dow3_flex1.csv} +0 -0
  163. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow3_flex2.csv → chg1_dow3_flex2.csv} +0 -0
  164. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg1_dow3_flex3.csv → chg1_dow3_flex3.csv} +0 -0
  165. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow1_flex1.csv → chg2_dow1_flex1.csv} +0 -0
  166. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow1_flex2.csv → chg2_dow1_flex2.csv} +0 -0
  167. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow1_flex3.csv → chg2_dow1_flex3.csv} +0 -0
  168. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow2_flex1.csv → chg2_dow2_flex1.csv} +0 -0
  169. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow2_flex2.csv → chg2_dow2_flex2.csv} +0 -0
  170. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow2_flex3.csv → chg2_dow2_flex3.csv} +0 -0
  171. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow3_flex1.csv → chg2_dow3_flex1.csv} +0 -0
  172. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow3_flex2.csv → chg2_dow3_flex2.csv} +0 -0
  173. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg2_dow3_flex3.csv → chg2_dow3_flex3.csv} +0 -0
  174. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow1_flex1.csv → chg3_dow1_flex1.csv} +0 -0
  175. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow1_flex2.csv → chg3_dow1_flex2.csv} +0 -0
  176. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow1_flex3.csv → chg3_dow1_flex3.csv} +0 -0
  177. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow2_flex1.csv → chg3_dow2_flex1.csv} +0 -0
  178. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow2_flex2.csv → chg3_dow2_flex2.csv} +0 -0
  179. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow2_flex3.csv → chg3_dow2_flex3.csv} +0 -0
  180. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow3_flex1.csv → chg3_dow3_flex1.csv} +0 -0
  181. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow3_flex2.csv → chg3_dow3_flex2.csv} +0 -0
  182. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/chg3_dow3_flex3.csv → chg3_dow3_flex3.csv} +0 -0
  183. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/fast_charge_15min_Saturday.csv → fast_charge_15min_Saturday.csv} +0 -0
  184. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/fast_charge_15min_Sunday.csv → fast_charge_15min_Sunday.csv} +0 -0
  185. data/lib/measures/add_ev_load/resources/{EV_Load_Profiles/fast_charge_15min_Weekday.csv → fast_charge_15min_Weekday.csv} +0 -0
  186. data/lib/measures/add_rooftop_pv/LICENSE.md +1 -1
  187. data/lib/measures/add_rooftop_pv/measure.rb +1 -1
  188. data/lib/measures/add_rooftop_pv/measure.xml +5 -5
  189. data/lib/measures/add_zone_mixing_object/LICENSE.md +1 -1
  190. data/lib/measures/add_zone_mixing_object/measure.rb +1 -1
  191. data/lib/measures/add_zone_mixing_object/measure.xml +8 -7
  192. data/lib/measures/add_zone_ventilation_design_flow_rate_object/LICENSE.md +1 -1
  193. data/lib/measures/add_zone_ventilation_design_flow_rate_object/measure.rb +1 -1
  194. data/lib/measures/add_zone_ventilation_design_flow_rate_object/measure.xml +8 -7
  195. data/lib/measures/air_wall_zone_mixing/LICENSE.md +1 -1
  196. data/lib/measures/air_wall_zone_mixing/measure.rb +1 -1
  197. data/lib/measures/air_wall_zone_mixing/measure.xml +5 -5
  198. data/lib/measures/envelope_and_internal_load_breakdown/LICENSE.md +1 -1
  199. data/lib/measures/envelope_and_internal_load_breakdown/measure.rb +1 -1
  200. data/lib/measures/envelope_and_internal_load_breakdown/measure.xml +8 -8
  201. data/lib/measures/envelope_and_internal_load_breakdown/resources/os_lib_reporting_envelope_and_internal_loads_breakdown.rb +1 -1
  202. data/lib/measures/envelope_and_internal_load_breakdown/resources/report.html.erb +4 -1
  203. data/lib/measures/example_report/LICENSE.md +1 -1
  204. data/lib/measures/example_report/measure.rb +1 -1
  205. data/lib/measures/example_report/measure.xml +14 -14
  206. data/lib/measures/example_report/resources/os_lib_reporting_example.rb +1 -1
  207. data/lib/measures/example_report/resources/report.html.erb +4 -1
  208. data/lib/measures/gem_env_report/LICENSE.md +1 -1
  209. data/lib/measures/gem_env_report/measure.rb +1 -1
  210. data/lib/measures/gem_env_report/measure.xml +13 -12
  211. data/lib/measures/gem_env_report/resources/gem_env_info.rb +1 -1
  212. data/lib/measures/gem_env_report/resources/openstudio_info.rb +1 -1
  213. data/lib/measures/gem_env_report/resources/run_gem_env_info.rb +1 -1
  214. data/lib/measures/gem_env_report/resources/run_openstudio_info.rb +1 -1
  215. data/lib/measures/generic_qaqc/LICENSE.md +1 -1
  216. data/lib/measures/generic_qaqc/measure.rb +6 -1
  217. data/lib/measures/generic_qaqc/measure.xml +48 -54
  218. data/lib/measures/generic_qaqc/resources/CreateResults.rb +1 -1
  219. data/lib/measures/generic_qaqc/resources/check_air_sys_temps.rb +1 -1
  220. data/lib/measures/generic_qaqc/resources/check_calibration.rb +1 -1
  221. data/lib/measures/generic_qaqc/resources/check_cond_zns.rb +1 -1
  222. data/lib/measures/generic_qaqc/resources/check_domestic_hot_water.rb +1 -1
  223. data/lib/measures/generic_qaqc/resources/check_envelope_conductance.rb +1 -1
  224. data/lib/measures/generic_qaqc/resources/check_eui_by_end_use.rb +1 -1
  225. data/lib/measures/generic_qaqc/resources/check_eui_reasonableness.rb +1 -1
  226. data/lib/measures/generic_qaqc/resources/check_fan_pwr.rb +1 -1
  227. data/lib/measures/generic_qaqc/resources/check_internal_loads.rb +1 -1
  228. data/lib/measures/generic_qaqc/resources/check_mech_sys_capacity.rb +1 -1
  229. data/lib/measures/generic_qaqc/resources/check_mech_sys_efficiency.rb +1 -1
  230. data/lib/measures/generic_qaqc/resources/check_mech_sys_part_load_eff.rb +1 -1
  231. data/lib/measures/generic_qaqc/resources/check_mech_sys_type.rb +1 -1
  232. data/lib/measures/generic_qaqc/resources/check_part_loads.rb +1 -1
  233. data/lib/measures/generic_qaqc/resources/check_placeholder.rb +1 -1
  234. data/lib/measures/generic_qaqc/resources/check_plant_cap.rb +1 -1
  235. data/lib/measures/generic_qaqc/resources/check_plant_temps.rb +1 -1
  236. data/lib/measures/generic_qaqc/resources/check_plenum_loads.rb +1 -1
  237. data/lib/measures/generic_qaqc/resources/check_pump_pwr.rb +1 -1
  238. data/lib/measures/generic_qaqc/resources/check_sch_coord.rb +1 -1
  239. data/lib/measures/generic_qaqc/resources/check_schedules.rb +1 -1
  240. data/lib/measures/generic_qaqc/resources/check_simultaneous_heating_and_cooling.rb +1 -1
  241. data/lib/measures/generic_qaqc/resources/check_supply_air_and_thermostat_temp_difference.rb +1 -1
  242. data/lib/measures/generic_qaqc/resources/check_weather_files.rb +1 -1
  243. data/lib/measures/generic_qaqc/resources/os_lib_reporting_qaqc.rb +1 -1
  244. data/lib/measures/generic_qaqc/resources/report.html.erb +4 -1
  245. data/lib/measures/get_site_from_building_component_library/LICENSE.md +1 -1
  246. data/lib/measures/get_site_from_building_component_library/measure.rb +1 -1
  247. data/lib/measures/get_site_from_building_component_library/measure.xml +6 -6
  248. data/lib/measures/hvac_psychrometric_chart/LICENSE.md +1 -1
  249. data/lib/measures/hvac_psychrometric_chart/measure.rb +1 -1
  250. data/lib/measures/hvac_psychrometric_chart/measure.xml +15 -16
  251. data/lib/measures/hvac_psychrometric_chart/resources/report.html.erb +4 -1
  252. data/lib/measures/inject_idf_objects/LICENSE.md +1 -1
  253. data/lib/measures/inject_idf_objects/measure.rb +1 -1
  254. data/lib/measures/inject_idf_objects/measure.xml +10 -10
  255. data/lib/measures/openstudio_results/LICENSE.md +1 -1
  256. data/lib/measures/openstudio_results/measure.rb +6 -4
  257. data/lib/measures/openstudio_results/measure.xml +174 -162
  258. data/lib/measures/openstudio_results/resources/Siz.AirConditionerVariableRefrigerantFlow.rb +1 -1
  259. data/lib/measures/openstudio_results/resources/Siz.AirLoopHVAC.rb +1 -1
  260. data/lib/measures/openstudio_results/resources/Siz.AirLoopHVACUnitaryHeatCoolVAVChangeoverBypass.rb +1 -1
  261. data/lib/measures/openstudio_results/resources/Siz.AirLoopHVACUnitaryHeatPumpAirToAir.rb +1 -1
  262. data/lib/measures/openstudio_results/resources/Siz.AirLoopHVACUnitaryHeatPumpAirToAirMultiSpeed.rb +1 -1
  263. data/lib/measures/openstudio_results/resources/Siz.AirLoopHVACUnitarySystem.rb +1 -1
  264. data/lib/measures/openstudio_results/resources/Siz.AirTerminalDualDuctVAV.rb +1 -1
  265. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctConstantVolumeCooledBeam.rb +1 -1
  266. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctConstantVolumeFourPipeInduction.rb +1 -1
  267. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctConstantVolumeReheat.rb +1 -1
  268. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctParallelPIUReheat.rb +1 -1
  269. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctSeriesPIUReheat.rb +1 -1
  270. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctUncontrolled.rb +1 -1
  271. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctVAVHeatAndCoolNoReheat.rb +1 -1
  272. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctVAVHeatAndCoolReheat.rb +1 -1
  273. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctVAVNoReheat.rb +1 -1
  274. data/lib/measures/openstudio_results/resources/Siz.AirTerminalSingleDuctVAVReheat.rb +1 -1
  275. data/lib/measures/openstudio_results/resources/Siz.BoilerHotWater.rb +1 -1
  276. data/lib/measures/openstudio_results/resources/Siz.BoilerSteam.rb +1 -1
  277. data/lib/measures/openstudio_results/resources/Siz.ChillerAbsorption.rb +1 -1
  278. data/lib/measures/openstudio_results/resources/Siz.ChillerAbsorptionIndirect.rb +1 -1
  279. data/lib/measures/openstudio_results/resources/Siz.ChillerElectricEIR.rb +1 -1
  280. data/lib/measures/openstudio_results/resources/Siz.ChillerHeaterPerformanceElectricEIR.rb +1 -1
  281. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXMultiSpeed.rb +1 -1
  282. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXMultiSpeedStageData.rb +1 -1
  283. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXSingleSpeed.rb +1 -1
  284. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXTwoSpeed.rb +1 -1
  285. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXTwoStageWithHumidityControlMode.rb +1 -1
  286. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXVariableRefrigerantFlow.rb +1 -1
  287. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXVariableSpeed.rb +1 -1
  288. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingDXVariableSpeedSpeedData.rb +1 -1
  289. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingLowTempRadiantVarFlow.rb +1 -1
  290. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingWater.rb +1 -1
  291. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingWaterToAirHeatPumpEquationFit.rb +1 -1
  292. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFit.rb +1 -1
  293. data/lib/measures/openstudio_results/resources/Siz.CoilCoolingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.rb +1 -1
  294. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDXMultiSpeed.rb +1 -1
  295. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDXMultiSpeedStageData.rb +1 -1
  296. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDXSingleSpeed.rb +1 -1
  297. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDXVariableRefrigerantFlow.rb +1 -1
  298. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDXVariableSpeed.rb +1 -1
  299. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDXVariableSpeedSpeedData.rb +1 -1
  300. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingDesuperheater.rb +1 -1
  301. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingElectric.rb +1 -1
  302. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingGas.rb +1 -1
  303. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingGasMultiStage.rb +1 -1
  304. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingGasMultiStageStageData.rb +1 -1
  305. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingLowTempRadiantVarFlow.rb +1 -1
  306. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingWater.rb +1 -1
  307. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingWaterBaseboard.rb +1 -1
  308. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingWaterBaseboardRadiant.rb +1 -1
  309. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingWaterToAirHeatPumpEquationFit.rb +1 -1
  310. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFit.rb +1 -1
  311. data/lib/measures/openstudio_results/resources/Siz.CoilHeatingWaterToAirHeatPumpVariableSpeedEquationFitSpeedData.rb +1 -1
  312. data/lib/measures/openstudio_results/resources/Siz.CoilPerformanceDXCooling.rb +1 -1
  313. data/lib/measures/openstudio_results/resources/Siz.CoilSystemCoolingDXHeatExchangerAssisted.rb +1 -1
  314. data/lib/measures/openstudio_results/resources/Siz.CoilSystemCoolingWaterHeatExchangerAssisted.rb +1 -1
  315. data/lib/measures/openstudio_results/resources/Siz.CoilWaterHeatingAirToWaterHeatPump.rb +1 -1
  316. data/lib/measures/openstudio_results/resources/Siz.CoilWaterHeatingAirToWaterHeatPumpWrapped.rb +1 -1
  317. data/lib/measures/openstudio_results/resources/Siz.CoilWaterHeatingDesuperheater.rb +1 -1
  318. data/lib/measures/openstudio_results/resources/Siz.ControllerOutdoorAir.rb +1 -1
  319. data/lib/measures/openstudio_results/resources/Siz.CoolingTowerSingleSpeed.rb +1 -1
  320. data/lib/measures/openstudio_results/resources/Siz.CoolingTowerTwoSpeed.rb +1 -1
  321. data/lib/measures/openstudio_results/resources/Siz.CoolingTowerVariableSpeed.rb +1 -1
  322. data/lib/measures/openstudio_results/resources/Siz.DistrictCooling.rb +1 -1
  323. data/lib/measures/openstudio_results/resources/Siz.DistrictHeating.rb +1 -1
  324. data/lib/measures/openstudio_results/resources/Siz.ElectricLoadCenterInverterLookUpTable.rb +1 -1
  325. data/lib/measures/openstudio_results/resources/Siz.ElectricLoadCenterInverterSimple.rb +1 -1
  326. data/lib/measures/openstudio_results/resources/Siz.ElectricLoadCenterStorageConverter.rb +1 -1
  327. data/lib/measures/openstudio_results/resources/Siz.ElectricLoadCenterStorageSimple.rb +1 -1
  328. data/lib/measures/openstudio_results/resources/Siz.EvaporativeCoolerDirectResearchSpecial.rb +1 -1
  329. data/lib/measures/openstudio_results/resources/Siz.EvaporativeCoolerIndirectResearchSpecial.rb +1 -1
  330. data/lib/measures/openstudio_results/resources/Siz.EvaporativeFluidCoolerSingleSpeed.rb +1 -1
  331. data/lib/measures/openstudio_results/resources/Siz.EvaporativeFluidCoolerTwoSpeed.rb +1 -1
  332. data/lib/measures/openstudio_results/resources/Siz.FanConstantVolume.rb +1 -1
  333. data/lib/measures/openstudio_results/resources/Siz.FanOnOff.rb +1 -1
  334. data/lib/measures/openstudio_results/resources/Siz.FanVariableVolume.rb +1 -1
  335. data/lib/measures/openstudio_results/resources/Siz.FanZoneExhaust.rb +1 -1
  336. data/lib/measures/openstudio_results/resources/Siz.FluidCoolerSingleSpeed.rb +1 -1
  337. data/lib/measures/openstudio_results/resources/Siz.FluidCoolerTwoSpeed.rb +1 -1
  338. data/lib/measures/openstudio_results/resources/Siz.GeneratorFuelCellElectricalStorage.rb +1 -1
  339. data/lib/measures/openstudio_results/resources/Siz.GeneratorFuelCellInverter.rb +1 -1
  340. data/lib/measures/openstudio_results/resources/Siz.GeneratorFuelCellPowerModule.rb +1 -1
  341. data/lib/measures/openstudio_results/resources/Siz.GeneratorMicroTurbine.rb +1 -1
  342. data/lib/measures/openstudio_results/resources/Siz.GeneratorMicroTurbineHeatRecovery.rb +1 -1
  343. data/lib/measures/openstudio_results/resources/Siz.HVACComponent.rb +1 -1
  344. data/lib/measures/openstudio_results/resources/Siz.HeaderedPumpsConstantSpeed.rb +1 -1
  345. data/lib/measures/openstudio_results/resources/Siz.HeaderedPumpsVariableSpeed.rb +1 -1
  346. data/lib/measures/openstudio_results/resources/Siz.HeatExchangerAirToAirSensibleAndLatent.rb +1 -1
  347. data/lib/measures/openstudio_results/resources/Siz.HeatExchangerFluidToFluid.rb +1 -1
  348. data/lib/measures/openstudio_results/resources/Siz.HeatPumpWaterToWaterEquationFitCooling.rb +1 -1
  349. data/lib/measures/openstudio_results/resources/Siz.HeatPumpWaterToWaterEquationFitHeating.rb +1 -1
  350. data/lib/measures/openstudio_results/resources/Siz.HumidifierSteamElectric.rb +1 -1
  351. data/lib/measures/openstudio_results/resources/Siz.Model.rb +1 -1
  352. data/lib/measures/openstudio_results/resources/Siz.ModelObject.rb +1 -1
  353. data/lib/measures/openstudio_results/resources/Siz.PhotovoltaicPerformanceSimple.rb +1 -1
  354. data/lib/measures/openstudio_results/resources/Siz.PlantComponentTemperatureSource.rb +1 -1
  355. data/lib/measures/openstudio_results/resources/Siz.PlantLoop.rb +1 -1
  356. data/lib/measures/openstudio_results/resources/Siz.PumpConstantSpeed.rb +1 -1
  357. data/lib/measures/openstudio_results/resources/Siz.PumpVariableSpeed.rb +1 -1
  358. data/lib/measures/openstudio_results/resources/Siz.RefrigerationSecondarySystem.rb +1 -1
  359. data/lib/measures/openstudio_results/resources/Siz.RefrigerationSystem.rb +1 -1
  360. data/lib/measures/openstudio_results/resources/Siz.RefrigerationTranscriticalSystem.rb +1 -1
  361. data/lib/measures/openstudio_results/resources/Siz.SizingSystem.rb +1 -1
  362. data/lib/measures/openstudio_results/resources/Siz.SolarCollectorFlatPlatePhotovoltaicThermal.rb +1 -1
  363. data/lib/measures/openstudio_results/resources/Siz.SolarCollectorPerformancePhotovoltaicThermalSimple.rb +1 -1
  364. data/lib/measures/openstudio_results/resources/Siz.ThermalStorageChilledWaterStratified.rb +1 -1
  365. data/lib/measures/openstudio_results/resources/Siz.WaterHeaterHeatPump.rb +1 -1
  366. data/lib/measures/openstudio_results/resources/Siz.WaterHeaterHeatPumpWrappedCondenser.rb +1 -1
  367. data/lib/measures/openstudio_results/resources/Siz.WaterHeaterMixed.rb +1 -1
  368. data/lib/measures/openstudio_results/resources/Siz.WaterHeaterStratified.rb +1 -1
  369. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACBaseboardConvectiveElectric.rb +1 -1
  370. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACBaseboardConvectiveWater.rb +1 -1
  371. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACBaseboardRadiantConvectiveElectric.rb +1 -1
  372. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACBaseboardRadiantConvectiveWater.rb +1 -1
  373. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACEnergyRecoveryVentilator.rb +1 -1
  374. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACFourPipeFanCoil.rb +1 -1
  375. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACHighTemperatureRadiant.rb +1 -1
  376. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACIdealLoadsAirSystem.rb +1 -1
  377. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACLowTempRadiantConstFlow.rb +1 -1
  378. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACLowTempRadiantVarFlow.rb +1 -1
  379. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACPackagedTerminalAirConditioner.rb +1 -1
  380. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACPackagedTerminalHeatPump.rb +1 -1
  381. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACTerminalUnitVariableRefrigerantFlow.rb +1 -1
  382. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACUnitHeater.rb +1 -1
  383. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACUnitVentilator.rb +1 -1
  384. data/lib/measures/openstudio_results/resources/Siz.ZoneHVACWaterToAirHeatPump.rb +1 -1
  385. data/lib/measures/openstudio_results/resources/Siz.ZoneVentilationDesignFlowRate.rb +1 -1
  386. data/lib/measures/openstudio_results/resources/os_lib_reporting.rb +2 -2
  387. data/lib/measures/openstudio_results/resources/report.html.erb +4 -1
  388. data/lib/measures/remove_orphan_objects_and_unused_resources/LICENSE.md +1 -1
  389. data/lib/measures/remove_orphan_objects_and_unused_resources/measure.rb +1 -1
  390. data/lib/measures/remove_orphan_objects_and_unused_resources/measure.xml +8 -7
  391. data/lib/measures/set_electric_equipment_loads_by_epd/LICENSE.md +1 -1
  392. data/lib/measures/set_electric_equipment_loads_by_epd/measure.rb +1 -1
  393. data/lib/measures/set_electric_equipment_loads_by_epd/measure.xml +10 -9
  394. data/lib/measures/set_exterior_walls_and_floors_to_adiabatic/LICENSE.md +1 -1
  395. data/lib/measures/set_exterior_walls_and_floors_to_adiabatic/measure.rb +1 -1
  396. data/lib/measures/set_exterior_walls_and_floors_to_adiabatic/measure.xml +17 -11
  397. data/lib/measures/set_run_period/LICENSE.md +1 -1
  398. data/lib/measures/set_run_period/measure.rb +1 -1
  399. data/lib/measures/set_run_period/measure.xml +5 -5
  400. data/lib/measures/set_space_infiltration_per_exterior_area/LICENSE.md +1 -1
  401. data/lib/measures/set_space_infiltration_per_exterior_area/measure.rb +1 -1
  402. data/lib/measures/set_space_infiltration_per_exterior_area/measure.xml +8 -7
  403. data/lib/measures/tariff_selection_block/LICENSE.md +1 -1
  404. data/lib/measures/tariff_selection_block/measure.rb +2 -2
  405. data/lib/measures/tariff_selection_block/measure.xml +5 -5
  406. data/lib/measures/tariff_selection_flat/LICENSE.md +1 -1
  407. data/lib/measures/tariff_selection_flat/measure.rb +2 -2
  408. data/lib/measures/tariff_selection_flat/measure.xml +5 -5
  409. data/lib/measures/tariff_selection_generic/LICENSE.md +1 -1
  410. data/lib/measures/tariff_selection_generic/README.md +2 -2
  411. data/lib/measures/tariff_selection_generic/measure.rb +1 -1
  412. data/lib/measures/tariff_selection_generic/measure.xml +25 -25
  413. data/lib/measures/tariff_selection_generic/resources/FlatEnergyCharge-Gas.idf +3 -3
  414. data/lib/measures/tariff_selection_generic/resources/IN-EIAMonthlyRateGas.idf +1 -1
  415. data/lib/measures/tariff_selection_time_and_date_dependant/LICENSE.md +1 -1
  416. data/lib/measures/tariff_selection_time_and_date_dependant/measure.rb +2 -2
  417. data/lib/measures/tariff_selection_time_and_date_dependant/measure.xml +5 -5
  418. data/lib/measures/view_data/LICENSE.md +1 -1
  419. data/lib/measures/view_data/measure.rb +1 -1
  420. data/lib/measures/view_data/measure.xml +30 -30
  421. data/lib/measures/view_data/resources/va3c.rb +1 -1
  422. data/lib/measures/view_model/LICENSE.md +1 -1
  423. data/lib/measures/view_model/measure.rb +1 -1
  424. data/lib/measures/view_model/measure.xml +47 -16
  425. data/lib/measures/view_model/resources/va3c.rb +1 -1
  426. data/lib/openstudio-common-measures.rb +1 -1
  427. data/lib/openstudio/common_measures.rb +1 -1
  428. data/lib/openstudio/common_measures/extension.rb +1 -1
  429. data/lib/openstudio/common_measures/version.rb +2 -2
  430. data/openstudio-common-measures.gemspec +4 -4
  431. metadata +42 -45
  432. data/lib/measures/generic_qaqc/resources/os_lib_helper_methods.rb +0 -399
  433. data/lib/measures/openstudio_results/resources/os_lib_helper_methods.rb +0 -399
  434. data/lib/measures/openstudio_results/resources/os_lib_schedules.rb +0 -962
@@ -1,399 +0,0 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
3
- # All rights reserved.
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are met:
6
- #
7
- # (1) Redistributions of source code must retain the above copyright notice,
8
- # this list of conditions and the following disclaimer.
9
- #
10
- # (2) Redistributions in binary form must reproduce the above copyright notice,
11
- # this list of conditions and the following disclaimer in the documentation
12
- # and/or other materials provided with the distribution.
13
- #
14
- # (3) Neither the name of the copyright holder nor the names of any contributors
15
- # may be used to endorse or promote products derived from this software without
16
- # specific prior written permission from the respective party.
17
- #
18
- # (4) Other than as required in clauses (1) and (2), distributions in any form
19
- # of modifications or other derivative works may not use the "OpenStudio"
20
- # trademark, "OS", "os", or any other confusingly similar designation without
21
- # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
- #
23
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
- # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
- # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
- # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
- # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
- # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
- # *******************************************************************************
35
-
36
- module OsLib_HelperMethods
37
- # populate choice argument from model objects
38
- def self.populateChoiceArgFromModelObjects(model, modelObject_args_hash, includeBuilding = nil)
39
- # populate choice argument for constructions that are applied to surfaces in the model
40
- modelObject_handles = OpenStudio::StringVector.new
41
- modelObject_display_names = OpenStudio::StringVector.new
42
-
43
- # looping through sorted hash of constructions
44
- modelObject_args_hash.sort.map do |key, value|
45
- modelObject_handles << value.handle.to_s
46
- modelObject_display_names << key
47
- end
48
-
49
- unless includeBuilding.nil?
50
- # add building to string vector with space type
51
- building = model.getBuilding
52
- modelObject_handles << building.handle.to_s
53
- modelObject_display_names << includeBuilding
54
- end
55
-
56
- result = { 'modelObject_handles' => modelObject_handles, 'modelObject_display_names' => modelObject_display_names }
57
- return result
58
- end
59
-
60
- # create variables in run from user arguments
61
- def self.createRunVariables(runner, model, user_arguments, arguments)
62
- result = {}
63
-
64
- error = false
65
- # use the built-in error checking
66
- unless runner.validateUserArguments(arguments, user_arguments)
67
- error = true
68
- runner.registerError('Invalid argument values.')
69
- end
70
-
71
- user_arguments.each do |argument|
72
- # get argument info
73
- arg = user_arguments[argument]
74
- arg_type = arg.print.lines($/)[1]
75
-
76
- # create argument variable
77
- if arg_type.include? 'Double, Required'
78
- eval("result[\"#{arg.name}\"] = runner.getDoubleArgumentValue(\"#{arg.name}\", user_arguments)")
79
- elsif arg_type.include? 'Integer, Required'
80
- eval("result[\"#{arg.name}\"] = runner.getIntegerArgumentValue(\"#{arg.name}\", user_arguments)")
81
- elsif arg_type.include? 'String, Required'
82
- eval("result[\"#{arg.name}\"] = runner.getStringArgumentValue(\"#{arg.name}\", user_arguments)")
83
- elsif arg_type.include? 'Boolean, Required'
84
- eval("result[\"#{arg.name}\"] = runner.getBoolArgumentValue(\"#{arg.name}\", user_arguments)")
85
- elsif arg_type.include? 'Choice, Required'
86
- eval("result[\"#{arg.name}\"] = runner.getStringArgumentValue(\"#{arg.name}\", user_arguments)")
87
- else
88
- puts 'not setup to handle all argument types yet, or any optional arguments'
89
- end
90
- end
91
-
92
- if error
93
- return false
94
- else
95
- return result
96
- end
97
- end
98
-
99
- # check choice argument made from model objects
100
- def self.checkChoiceArgFromModelObjects(object, variableName, to_ObjectType, runner, user_arguments)
101
- apply_to_building = false
102
- modelObject = nil
103
- if object.empty?
104
- handle = runner.getStringArgumentValue(variableName, user_arguments)
105
- if handle.empty?
106
- runner.registerError("No #{variableName} was chosen.") # this logic makes this not work on an optional model object argument
107
- else
108
- runner.registerError("The selected #{variableName} with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
109
- end
110
- return false
111
- else
112
- if !eval("object.get.#{to_ObjectType}").empty?
113
- modelObject = eval("object.get.#{to_ObjectType}").get
114
- elsif !object.get.to_Building.empty?
115
- apply_to_building = true
116
- else
117
- runner.registerError("Script Error - argument not showing up as #{variableName}.")
118
- return false
119
- end
120
- end
121
-
122
- result = { 'modelObject' => modelObject, 'apply_to_building' => apply_to_building }
123
- end
124
-
125
- # check choice argument made from model objects
126
- def self.checkOptionalChoiceArgFromModelObjects(object, variableName, to_ObjectType, runner, user_arguments)
127
- apply_to_building = false
128
- modelObject = nil
129
- if object.empty?
130
- handle = runner.getOptionalStringArgumentValue(variableName, user_arguments)
131
- if handle.empty?
132
- # do nothing, this is a valid option
133
- puts 'hello'
134
- modelObject = nil
135
- apply_to_building = false
136
- else
137
- runner.registerError("The selected #{variableName} with handle '#{handle}' was not found in the model. It may have been removed by another measure.")
138
- return false
139
- end
140
- else
141
- if !eval("object.get.#{to_ObjectType}").empty?
142
- modelObject = eval("object.get.#{to_ObjectType}").get
143
- elsif !object.get.to_Building.empty?
144
- apply_to_building = true
145
- else
146
- runner.registerError("Script Error - argument not showing up as #{variableName}.")
147
- return false
148
- end
149
- end
150
-
151
- result = { 'modelObject' => modelObject, 'apply_to_building' => apply_to_building }
152
- end
153
-
154
- # check value of double arguments
155
- def self.checkDoubleAndIntegerArguments(runner, user_arguments, arg_check_hash)
156
- error = false
157
-
158
- # get hash values
159
- min = arg_check_hash['min']
160
- max = arg_check_hash['max']
161
- min_eq_bool = arg_check_hash['min_eq_bool']
162
- max_eq_bool = arg_check_hash['max_eq_bool']
163
-
164
- arg_check_hash['arg_array'].each do |argument|
165
- argument = user_arguments[argument]
166
-
167
- # get arg values
168
- arg_value = nil
169
- if argument.hasValue
170
- arg_value = argument.valueDisplayName.to_f # instead of valueAsDouble so it allows integer arguments as well
171
- elsif argument.hasDefaultValue
172
- arg_value = argument.defaultValueDisplayName.to_f
173
- end
174
- arg_display = argument.displayName
175
-
176
- unless min.nil?
177
- if min_eq_bool
178
- if arg_value < min
179
- runner.registerError("Please enter value greater than or equal to #{min} for #{arg_display}.") # add in argument display name
180
- error = true
181
- end
182
- else
183
- if arg_value <= min
184
- runner.registerError("Please enter value greater than #{min} for #{arg_display}.") # add in argument display name
185
- error = true
186
- end
187
- end
188
- end
189
- unless max.nil?
190
- if max_eq_bool
191
- if arg_value > max
192
- runner.registerError("Please enter value less than or equal to #{max} for #{arg_display}.") # add in argument display name
193
- error = true
194
- end
195
- else
196
- if arg_value >= max
197
- runner.registerError("Please enter value less than #{max} for #{arg_display}.") # add in argument display name
198
- error = true
199
- end
200
- end
201
- end
202
- end
203
-
204
- # check for any errors
205
- if error
206
- return false
207
- else
208
- return true
209
- end
210
- end
211
-
212
- # open channel to log info/warning/error messages
213
- def self.setup_log_msgs(runner, debug = false)
214
- # Open a channel to log info/warning/error messages
215
- @msg_log = OpenStudio::StringStreamLogSink.new
216
- if debug
217
- @msg_log.setLogLevel(OpenStudio::Debug)
218
- else
219
- @msg_log.setLogLevel(OpenStudio::Info)
220
- end
221
- @start_time = Time.new
222
- @runner = runner
223
- end
224
-
225
- # Get all the log messages and put into output
226
- # for users to see.
227
- def self.log_msgs
228
- @msg_log.logMessages.each do |msg|
229
- # DLM: you can filter on log channel here for now
230
- if /openstudio.*/.match(msg.logChannel) # /openstudio\.model\..*/
231
- # Skip certain messages that are irrelevant/misleading
232
- next if msg.logMessage.include?('Skipping layer') || # Annoying/bogus "Skipping layer" warnings
233
- msg.logChannel.include?('runmanager') || # RunManager messages
234
- msg.logChannel.include?('setFileExtension') || # .ddy extension unexpected
235
- msg.logChannel.include?('Translator') || # Forward translator and geometry translator
236
- msg.logMessage.include?('UseWeatherFile') # 'UseWeatherFile' is not yet a supported option for YearDescription
237
-
238
- # Report the message in the correct way
239
- if msg.logLevel == OpenStudio::Info
240
- @runner.registerInfo(msg.logMessage)
241
- elsif msg.logLevel == OpenStudio::Warn
242
- @runner.registerWarning("[#{msg.logChannel}] #{msg.logMessage}")
243
- elsif msg.logLevel == OpenStudio::Error
244
- @runner.registerError("[#{msg.logChannel}] #{msg.logMessage}")
245
- elsif msg.logLevel == OpenStudio::Debug && @debug
246
- @runner.registerInfo("DEBUG - #{msg.logMessage}")
247
- end
248
- end
249
- end
250
- @runner.registerInfo("Total Time = #{(Time.new - @start_time).round}sec.")
251
- end
252
-
253
- def self.check_upstream_measure_for_arg(runner, arg_name)
254
- # 2.x methods (currently setup for measure display name but snake_case arg names)
255
- arg_name_value = {}
256
- runner.workflow.workflowSteps.each do |step|
257
- if step.to_MeasureStep.is_initialized
258
- measure_step = step.to_MeasureStep.get
259
-
260
- measure_name = measure_step.measureDirName
261
- if measure_step.name.is_initialized
262
- measure_name = measure_step.name.get # this is instance name in PAT
263
- end
264
- if measure_step.result.is_initialized
265
- result = measure_step.result.get
266
- result.stepValues.each do |arg|
267
- name = arg.name
268
- value = arg.valueAsVariant.to_s
269
- if name == arg_name
270
- arg_name_value[:value] = value
271
- arg_name_value[:measure_name] = measure_name
272
- return arg_name_value # stop after find first one
273
- end
274
- end
275
- else
276
- # puts "No result for #{measure_name}"
277
- end
278
- else
279
- # puts "This step is not a measure"
280
- end
281
- end
282
-
283
- return arg_name_value
284
- end
285
-
286
- # populate choice argument from model objects. areaType should be string like "floorArea" or "exteriorArea"
287
- # note: it seems like spaceType.floorArea does account for multiplier, so I don't have to call this method unless I have a custom collection of spaces.
288
- def self.getAreaOfSpacesInArray(model, spaceArray, areaType = 'floorArea')
289
- # find selected floor spaces, make array and get floor area.
290
- totalArea = 0
291
- spaceAreaHash = {}
292
- spaceArray.each do |space|
293
- spaceArea = eval("space.#{areaType}*space.multiplier")
294
- spaceAreaHash[space] = spaceArea
295
- totalArea += spaceArea
296
- end
297
-
298
- result = { 'totalArea' => totalArea, 'spaceAreaHash' => spaceAreaHash }
299
- return result
300
- end
301
-
302
- # runs conversion and neat string, and returns value with units in string, optionally before or after the value
303
- def self.neatConvertWithUnitDisplay(double, fromString, toString, digits, unitBefore = false, unitAfter = true, space = true, parentheses = true)
304
- # convert units
305
- doubleConverted = OpenStudio.convert(double, fromString, toString)
306
- if !doubleConverted.nil?
307
- doubleConverted = doubleConverted.get
308
- else
309
- puts "Couldn't convert values, check string choices passed in. From: #{fromString}, To: #{toString}"
310
- end
311
-
312
- # get neat version of converted
313
- neatConverted = OpenStudio.toNeatString(doubleConverted, digits, true)
314
-
315
- # add prefix
316
- if unitBefore
317
- if space == true && parentheses == true
318
- prefix = "(#{toString}) "
319
- elsif space == true && parentheses == false
320
- prefix = "(#{toString})"
321
- elsif space == false && parentheses == true
322
- prefix = "#{toString} "
323
- else
324
- prefix = toString.to_s
325
- end
326
- else
327
- prefix = ''
328
- end
329
-
330
- # add suffix
331
- if unitAfter
332
- if space == true && parentheses == true
333
- suffix = " (#{toString})"
334
- elsif space == true && parentheses == false
335
- suffix = "(#{toString})"
336
- elsif space == false && parentheses == true
337
- suffix = " #{toString}"
338
- else
339
- suffix = toString.to_s
340
- end
341
- else
342
- suffix = ''
343
- end
344
-
345
- finalString = "#{prefix}#{neatConverted}#{suffix}"
346
-
347
- return finalString
348
- end
349
-
350
- # helper that loops through lifecycle costs getting total costs under "Construction" and add to counter if occurs during year 0
351
- def self.getTotalCostForObjects(objectArray, category = 'Construction', onlyYearFromStartZero = true)
352
- counter = 0
353
- objectArray.each do |object|
354
- object_LCCs = object.lifeCycleCosts
355
- object_LCCs.each do |object_LCC|
356
- if object_LCC.category == category
357
- if onlyYearFromStartZero == false || object_LCC.yearsFromStart == 0
358
- counter += object_LCC.totalCost
359
- end
360
- end
361
- end
362
- end
363
-
364
- return counter
365
- end
366
-
367
- # helper that loops through lifecycle costs getting total costs under "Construction" and add to counter if occurs during year 0
368
- def self.getSpaceTypeStandardsInformation(spaceTypeArray)
369
- # hash of space types
370
- spaceTypeStandardsInfoHash = {}
371
-
372
- spaceTypeArray.each do |spaceType|
373
- # get standards building
374
- if !spaceType.standardsBuildingType.empty?
375
- standardsBuilding = spaceType.standardsBuildingType.get
376
- else
377
- standardsBuilding = nil
378
- end
379
-
380
- # get standards space type
381
- if !spaceType.standardsSpaceType.empty?
382
- standardsSpaceType = spaceType.standardsSpaceType.get
383
- else
384
- standardsSpaceType = nil
385
- end
386
-
387
- # populate hash
388
- spaceTypeStandardsInfoHash[spaceType] = [standardsBuilding, standardsSpaceType]
389
- end
390
-
391
- return spaceTypeStandardsInfoHash
392
- end
393
-
394
- # OpenStudio has built in toNeatString method
395
- # OpenStudio::toNeatString(double,2,true)# double,decimals, show commas
396
-
397
- # OpenStudio has built in helper for unit conversion. That can be done using OpenStudio::convert() as shown below.
398
- # OpenStudio::convert(double,"from unit string","to unit string").get
399
- end
@@ -1,962 +0,0 @@
1
- # *******************************************************************************
2
- # OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
3
- # All rights reserved.
4
- # Redistribution and use in source and binary forms, with or without
5
- # modification, are permitted provided that the following conditions are met:
6
- #
7
- # (1) Redistributions of source code must retain the above copyright notice,
8
- # this list of conditions and the following disclaimer.
9
- #
10
- # (2) Redistributions in binary form must reproduce the above copyright notice,
11
- # this list of conditions and the following disclaimer in the documentation
12
- # and/or other materials provided with the distribution.
13
- #
14
- # (3) Neither the name of the copyright holder nor the names of any contributors
15
- # may be used to endorse or promote products derived from this software without
16
- # specific prior written permission from the respective party.
17
- #
18
- # (4) Other than as required in clauses (1) and (2), distributions in any form
19
- # of modifications or other derivative works may not use the "OpenStudio"
20
- # trademark, "OS", "os", or any other confusingly similar designation without
21
- # specific prior written permission from Alliance for Sustainable Energy, LLC.
22
- #
23
- # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
24
- # "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
25
- # THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26
- # ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
27
- # UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
28
- # THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
29
- # EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
30
- # OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
- # INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32
- # STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
- # OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34
- # *******************************************************************************
35
-
36
- module OsLib_Schedules
37
- # create a ruleset schedule with a basic profile
38
- def self.createSimpleSchedule(model, options = {})
39
- defaults = {
40
- 'name' => nil,
41
- 'winterTimeValuePairs' => { 24.0 => 0.0 },
42
- 'summerTimeValuePairs' => { 24.0 => 1.0 },
43
- 'defaultTimeValuePairs' => { 24.0 => 1.0 }
44
- }
45
-
46
- # merge user inputs with defaults
47
- options = defaults.merge(options)
48
-
49
- # ScheduleRuleset
50
- sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
51
- if name
52
- sch_ruleset.setName(options['name'])
53
- end
54
-
55
- # Winter Design Day
56
- winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
57
- sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
58
- winter_dsn_day = sch_ruleset.winterDesignDaySchedule
59
- winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
60
- options['winterTimeValuePairs'].each do |k, v|
61
- hour = k.truncate
62
- min = ((k - hour) * 60).to_i
63
- winter_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0), v)
64
- end
65
-
66
- # Summer Design Day
67
- summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
68
- sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
69
- summer_dsn_day = sch_ruleset.summerDesignDaySchedule
70
- summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
71
- options['summerTimeValuePairs'].each do |k, v|
72
- hour = k.truncate
73
- min = ((k - hour) * 60).to_i
74
- summer_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0), v)
75
- end
76
-
77
- # All Days
78
- default_day = sch_ruleset.defaultDaySchedule
79
- default_day.setName("#{sch_ruleset.name} Schedule Week Day")
80
- options['defaultTimeValuePairs'].each do |k, v|
81
- hour = k.truncate
82
- min = ((k - hour) * 60).to_i
83
- default_day.addValue(OpenStudio::Time.new(0, hour, min, 0), v)
84
- end
85
-
86
- result = sch_ruleset
87
- return result
88
- end
89
-
90
- # find the maximum profile value for a schedule
91
- def self.getMinMaxAnnualProfileValue(model, schedule)
92
- # validate schedule
93
- if schedule.to_ScheduleRuleset.is_initialized
94
- schedule = schedule.to_ScheduleRuleset.get
95
-
96
- # gather profiles
97
- profiles = []
98
- defaultProfile = schedule.to_ScheduleRuleset.get.defaultDaySchedule
99
- profiles << defaultProfile
100
- rules = schedule.scheduleRules
101
- rules.each do |rule|
102
- profiles << rule.daySchedule
103
- end
104
-
105
- # test profiles
106
- min = nil
107
- max = nil
108
- profiles.each do |profile|
109
- profile.values.each do |value|
110
- if min.nil?
111
- min = value
112
- else
113
- if min > value then min = value end
114
- end
115
- if max.nil?
116
- max = value
117
- else
118
- if max < value then max = value end
119
- end
120
- end
121
- end
122
- result = { 'min' => min, 'max' => max } # this doesn't include summer and winter design day
123
- else
124
- result = nil
125
- end
126
-
127
- return result
128
- end
129
-
130
- # find the maximum profile value for a schedule
131
- def self.simpleScheduleValueAdjust(model, schedule, double, modificationType = 'Multiplier') # can increase/decrease by percentage or static value
132
- # TODO: - add in design days, maybe as optional argument
133
-
134
- # give option to clone or not
135
-
136
- # gather profiles
137
- profiles = []
138
- defaultProfile = schedule.to_ScheduleRuleset.get.defaultDaySchedule
139
- profiles << defaultProfile
140
- rules = schedule.scheduleRules
141
- rules.each do |rule|
142
- profiles << rule.daySchedule
143
- end
144
-
145
- # alter profiles
146
- profiles.each do |profile|
147
- times = profile.times
148
- i = 0
149
- profile.values.each do |value|
150
- if modificationType == 'Multiplier' || modificationType == 'Percentage' # percentage was used early on but Multiplier is preferable
151
- profile.addValue(times[i], value * double)
152
- end
153
- if modificationType == 'Sum' || modificationType == 'Value' # value was used early on but Sum is preferable
154
- profile.addValue(times[i], value + double)
155
- end
156
- i += 1
157
- end
158
- end
159
-
160
- result = schedule
161
- return result
162
- end
163
-
164
- # change value when value passes/fails test
165
- def self.conditionalScheduleValueAdjust(model, schedule, valueTestDouble, passDouble, failDouble, floorDouble, modificationType = 'Multiplier') # can increase/decrease by percentage or static value
166
- # TODO: - add in design days, maybe as optional argument
167
-
168
- # give option to clone or not
169
-
170
- # gather profiles
171
- profiles = []
172
- defaultProfile = schedule.to_ScheduleRuleset.get.defaultDaySchedule
173
- profiles << defaultProfile
174
- rules = schedule.scheduleRules
175
- rules.each do |rule|
176
- profiles << rule.daySchedule
177
- end
178
-
179
- # alter profiles
180
- profiles.each do |profile|
181
- times = profile.times
182
- i = 0
183
-
184
- profile.values.each do |value|
185
- # run test on this value
186
- if value < valueTestDouble
187
- double = passDouble
188
- else
189
- double = failDouble
190
- end
191
-
192
- # skip if value is floor or less
193
- next if value <= floorDouble
194
-
195
- if modificationType == 'Multiplier'
196
- profile.addValue(times[i], [value * double, floorDouble].max) # take the max of the floor or resulting value
197
- end
198
- if modificationType == 'Sum'
199
- profile.addValue(times[i], [value + double, floorDouble].max) # take the max of the floor or resulting value
200
- end
201
- i += 1
202
- end
203
- end
204
-
205
- result = schedule
206
- return result
207
- end
208
-
209
- # change value when time passes test
210
- def self.timeConditionalScheduleValueAdjust(model, schedule, hhmm_before, hhmm__after, inside_double, outside_double, modificationType = 'Multiplier') # can increase/decrease by percentage or static value
211
- # setup variables
212
- array = hhmm_before.to_s.split('')
213
- before_hour = "#{array[0]}#{array[1]}".to_i
214
- before_min = "#{array[2]}#{array[3]}".to_i
215
- array = hhmm__after.to_s.split('')
216
- after_hour = "#{array[0]}#{array[1]}".to_i
217
- after_min = "#{array[2]}#{array[3]}".to_i
218
-
219
- # gather profiles
220
- profiles = []
221
- schedule = schedule.to_ScheduleRuleset.get
222
- defaultProfile = schedule.defaultDaySchedule
223
- profiles << defaultProfile
224
- rules = schedule.scheduleRules
225
- rules.each do |rule|
226
- profiles << rule.daySchedule
227
- end
228
-
229
- # alter profiles
230
- profiles.each do |day_sch|
231
- times = day_sch.times
232
- i = 0
233
-
234
- # set times special times needed for methods below
235
- before_time = OpenStudio::Time.new(0, before_hour, before_min, 0)
236
- after_time = OpenStudio::Time.new(0, after_hour, after_min, 0)
237
- # day_end_time = OpenStudio::Time.new(0, 24, 0, 0)
238
-
239
- # add datapoint at before and after time
240
- original_value_at_before_time = day_sch.getValue(before_time)
241
- original_value_at_after_time = day_sch.getValue(after_time)
242
- day_sch.addValue(before_time, original_value_at_before_time)
243
- day_sch.addValue(after_time, original_value_at_after_time)
244
-
245
- # make arrays for original times and values
246
- times = day_sch.times
247
- values = day_sch.values
248
- day_sch.clearValues
249
-
250
- # make arrays for new values
251
- new_times = []
252
- new_values = []
253
-
254
- # loop through original time/value pairs to populate new array
255
- for i in 0..(values.length - 1)
256
- new_times << times[i]
257
-
258
- if times[i] > before_time && times[i] <= after_time # updated this so times[i] == before_time goes into the else
259
- if inside_double.nil?
260
- new_values << values[i]
261
- elsif modificationType == 'Sum'
262
- new_values << inside_double + values[i]
263
- elsif modificationType == 'Replace'
264
- new_values << inside_double
265
- else # should be Multiplier
266
- new_values << inside_double * values[i]
267
- end
268
- else
269
- if outside_double.nil?
270
- new_values << values[i]
271
- elsif modificationType == 'Sum'
272
- new_values << outside_double + values[i]
273
- elsif modificationType == 'Replace'
274
- new_values << outside_double
275
- else # should be Multiplier
276
- new_values << outside_double * values[i]
277
- end
278
- end
279
-
280
- end
281
-
282
- # generate new day_sch values
283
- for i in 0..(new_values.length - 1)
284
- day_sch.addValue(new_times[i], new_values[i])
285
- end
286
- end
287
-
288
- result = schedule
289
- return result
290
- end
291
-
292
- # merge multiple schedules into one using load or other value to weight each schedules influence on the merge
293
- def self.weightedMergeScheduleRulesets(model, scheduleWeighHash)
294
- # WARNING NOT READY FOR GENERAL USE YET - this doesn't do anything with rules yet, just winter, summer, and default profile
295
-
296
- # get denominator for weight
297
- denominator = 0
298
- scheduleWeighHash.each do |schedule, weight|
299
- denominator += weight
300
- end
301
-
302
- # create new schedule
303
- sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
304
- sch_ruleset.setName('Merged Schedule') # TODO: - make this optional user argument
305
-
306
- # create winter design day profile
307
- winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
308
- sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
309
- winter_dsn_day = sch_ruleset.winterDesignDaySchedule
310
- winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
311
-
312
- # create summer design day profile
313
- summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
314
- sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
315
- summer_dsn_day = sch_ruleset.summerDesignDaySchedule
316
- summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
317
-
318
- # create default profile
319
- default_day = sch_ruleset.defaultDaySchedule
320
- default_day.setName("#{sch_ruleset.name} Schedule Week Day")
321
-
322
- # hash of schedule rules
323
- rulesHash = {} # mon, tue, wed, thur, fri, sat, sun, startDate, endDate
324
- # to avoid stacking order issues across schedules, I may need to make a rule for each day of the week for each date range
325
-
326
- scheduleWeighHash.each do |schedule, weight|
327
- # populate winter design day profile
328
- oldWinterProfile = schedule.to_ScheduleRuleset.get.winterDesignDaySchedule
329
- times_final = summer_dsn_day.times
330
- i = 0
331
- valueUpdatedArray = []
332
- # loop through times already in profile and update values
333
- until i > times_final.size - 1
334
- value = oldWinterProfile.getValue(times_final[i]) * weight / denominator
335
- starting_value = winter_dsn_day.getValue(times_final[i])
336
- winter_dsn_day.addValue(times_final[i], value + starting_value)
337
- valueUpdatedArray << times_final[i]
338
- i += 1
339
- end
340
- # loop through any new times unique to the current old profile to be merged
341
- j = 0
342
- times = oldWinterProfile.times
343
- values = oldWinterProfile.values
344
- until j > times.size - 1
345
- unless valueUpdatedArray.include? times[j]
346
- value = values[j] * weight / denominator
347
- starting_value = winter_dsn_day.getValue(times[j])
348
- winter_dsn_day.addValue(times[j], value + starting_value)
349
- end
350
- j += 1
351
- end
352
-
353
- # populate summer design day profile
354
- oldSummerProfile = schedule.to_ScheduleRuleset.get.summerDesignDaySchedule
355
- times_final = summer_dsn_day.times
356
- i = 0
357
- valueUpdatedArray = []
358
- # loop through times already in profile and update values
359
- until i > times_final.size - 1
360
- value = oldSummerProfile.getValue(times_final[i]) * weight / denominator
361
- starting_value = summer_dsn_day.getValue(times_final[i])
362
- summer_dsn_day.addValue(times_final[i], value + starting_value)
363
- valueUpdatedArray << times_final[i]
364
- i += 1
365
- end
366
- # loop through any new times unique to the current old profile to be merged
367
- j = 0
368
- times = oldSummerProfile.times
369
- values = oldSummerProfile.values
370
- until j > times.size - 1
371
- unless valueUpdatedArray.include? times[j]
372
- value = values[j] * weight / denominator
373
- starting_value = summer_dsn_day.getValue(times[j])
374
- summer_dsn_day.addValue(times[j], value + starting_value)
375
- end
376
- j += 1
377
- end
378
-
379
- # populate default profile
380
- oldDefaultProfile = schedule.to_ScheduleRuleset.get.defaultDaySchedule
381
- times_final = default_day.times
382
- i = 0
383
- valueUpdatedArray = []
384
- # loop through times already in profile and update values
385
- until i > times_final.size - 1
386
- value = oldDefaultProfile.getValue(times_final[i]) * weight / denominator
387
- starting_value = default_day.getValue(times_final[i])
388
- default_day.addValue(times_final[i], value + starting_value)
389
- valueUpdatedArray << times_final[i]
390
- i += 1
391
- end
392
- # loop through any new times unique to the current old profile to be merged
393
- j = 0
394
- times = oldDefaultProfile.times
395
- values = oldDefaultProfile.values
396
- until j > times.size - 1
397
- unless valueUpdatedArray.include? times[j]
398
- value = values[j] * weight / denominator
399
- starting_value = default_day.getValue(times[j])
400
- default_day.addValue(times[j], value + starting_value)
401
- end
402
- j += 1
403
- end
404
-
405
- # create rules
406
-
407
- # gather data for rule profiles
408
-
409
- # populate rule profiles
410
- end
411
-
412
- result = { 'mergedSchedule' => sch_ruleset, 'denominator' => denominator }
413
- return result
414
- end
415
-
416
- # create a new schedule using absolute velocity of existing schedule
417
- def self.scheduleFromRateOfChange(model, schedule)
418
- # clone source schedule
419
- newSchedule = schedule.clone(model)
420
- newSchedule.setName("#{schedule.name} - Rate of Change")
421
- newSchedule = newSchedule.to_ScheduleRuleset.get
422
-
423
- # create array of all profiles to change. This includes summer, winter, default, and rules
424
- profiles = []
425
- profiles << newSchedule.winterDesignDaySchedule
426
- profiles << newSchedule.summerDesignDaySchedule
427
- profiles << newSchedule.defaultDaySchedule
428
-
429
- # time values may need
430
- endProfileTime = OpenStudio::Time.new(0, 24, 0, 0)
431
- hourBumpTime = OpenStudio::Time.new(0, 1, 0, 0)
432
- oneHourLeftTime = OpenStudio::Time.new(0, 23, 0, 0)
433
-
434
- rules = newSchedule.scheduleRules
435
- rules.each do |rule|
436
- profiles << rule.daySchedule
437
- end
438
-
439
- profiles.uniq.each do |profile|
440
- times = profile.times
441
- values = profile.values
442
-
443
- i = 0
444
- valuesIntermediate = []
445
- timesIntermediate = []
446
- until i == values.size
447
- if i == 0
448
- valuesIntermediate << 0.0
449
- if times[i] > hourBumpTime
450
- timesIntermediate << times[i] - hourBumpTime
451
- if times[i + 1].nil?
452
- timeStepValue = endProfileTime.hours + endProfileTime.minutes / 60 - times[i].hours - times[i].minutes / 60
453
- else
454
- timeStepValue = times[i + 1].hours + times[i + 1].minutes / 60 - times[i].hours - times[i].minutes / 60
455
- end
456
- valuesIntermediate << (values[i + 1].to_f - values[i].to_f).abs / (timeStepValue * 2)
457
- end
458
- timesIntermediate << times[i]
459
- elsif i == (values.size - 1)
460
- if times[times.size - 2] < oneHourLeftTime
461
- timesIntermediate << times[times.size - 2] + hourBumpTime # this should be the second to last time
462
- timeStepValue = times[i - 1].hours + times[i - 1].minutes / 60 - times[i - 2].hours - times[i - 2].minutes / 60
463
- valuesIntermediate << (values[i - 1].to_f - values[i - 2].to_f).abs / (timeStepValue * 2)
464
- end
465
- valuesIntermediate << 0.0
466
- timesIntermediate << times[i] # this should be the last time
467
- else
468
- # get value multiplier based on how many hours it is spread over
469
- timeStepValue = times[i].hours + times[i].minutes / 60 - times[i - 1].hours - times[i - 1].minutes / 60
470
- valuesIntermediate << (values[i].to_f - values[i - 1].to_f).abs / timeStepValue
471
- timesIntermediate << times[i]
472
- end
473
- i += 1
474
- end
475
-
476
- # delete all profile values
477
- profile.clearValues
478
-
479
- i = 0
480
- until i == timesIntermediate.size
481
- if i == (timesIntermediate.size - 1)
482
- profile.addValue(timesIntermediate[i], valuesIntermediate[i].to_f)
483
- else
484
- profile.addValue(timesIntermediate[i], valuesIntermediate[i].to_f)
485
- end
486
- i += 1
487
- end
488
- end
489
-
490
- # fix velocity so it isn't fraction change per step, but per hour (I need to count hours between times and divide value by this)
491
-
492
- result = newSchedule
493
- return result
494
- end
495
-
496
- # create a complex ruleset schedule
497
- def self.createComplexSchedule(model, options = {})
498
- defaults = {
499
- 'name' => nil,
500
- 'default_day' => ['always_on', [24.0, 1.0]]
501
- }
502
-
503
- # merge user inputs with defaults
504
- options = defaults.merge(options)
505
-
506
- # ScheduleRuleset
507
- sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
508
- if name
509
- sch_ruleset.setName(options['name'])
510
- end
511
-
512
- # Winter Design Day
513
- unless options['winter_design_day'].nil?
514
- winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
515
- sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
516
- winter_dsn_day = sch_ruleset.winterDesignDaySchedule
517
- winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
518
- options['winter_design_day'].each do |data_pair|
519
- hour = data_pair[0].truncate
520
- min = ((data_pair[0] - hour) * 60).to_i
521
- winter_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0), data_pair[1])
522
- end
523
- end
524
-
525
- # Summer Design Day
526
- unless options['summer_design_day'].nil?
527
- summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
528
- sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
529
- summer_dsn_day = sch_ruleset.summerDesignDaySchedule
530
- summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
531
- options['summer_design_day'].each do |data_pair|
532
- hour = data_pair[0].truncate
533
- min = ((data_pair[0] - hour) * 60).to_i
534
- summer_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0), data_pair[1])
535
- end
536
- end
537
-
538
- # Default Day
539
- default_day = sch_ruleset.defaultDaySchedule
540
- default_day.setName("#{sch_ruleset.name} #{options['default_day'][0]}")
541
- default_data_array = options['default_day']
542
- default_data_array.delete_at(0)
543
- default_data_array.each do |data_pair|
544
- hour = data_pair[0].truncate
545
- min = ((data_pair[0] - hour) * 60).to_i
546
- default_day.addValue(OpenStudio::Time.new(0, hour, min, 0), data_pair[1])
547
- end
548
-
549
- # Rules
550
- unless options['rules'].nil?
551
- options['rules'].each do |data_array|
552
- rule = OpenStudio::Model::ScheduleRule.new(sch_ruleset)
553
- rule.setName("#{sch_ruleset.name} #{data_array[0]} Rule")
554
- date_range = data_array[1].split('-')
555
- start_date = date_range[0].split('/')
556
- end_date = date_range[1].split('/')
557
- rule.setStartDate(model.getYearDescription.makeDate(start_date[0].to_i, start_date[1].to_i))
558
- rule.setEndDate(model.getYearDescription.makeDate(end_date[0].to_i, end_date[1].to_i))
559
- days = data_array[2].split('/')
560
- rule.setApplySunday(true) if days.include? 'Sun'
561
- rule.setApplyMonday(true) if days.include? 'Mon'
562
- rule.setApplyTuesday(true) if days.include? 'Tue'
563
- rule.setApplyWednesday(true) if days.include? 'Wed'
564
- rule.setApplyThursday(true) if days.include? 'Thu'
565
- rule.setApplyFriday(true) if days.include? 'Fri'
566
- rule.setApplySaturday(true) if days.include? 'Sat'
567
- day_schedule = rule.daySchedule
568
- day_schedule.setName("#{sch_ruleset.name} #{data_array[0]}")
569
- data_array.delete_at(0)
570
- data_array.delete_at(0)
571
- data_array.delete_at(0)
572
- data_array.each do |data_pair|
573
- hour = data_pair[0].truncate
574
- min = ((data_pair[0] - hour) * 60).to_i
575
- day_schedule.addValue(OpenStudio::Time.new(0, hour, min, 0), data_pair[1])
576
- end
577
- end
578
- end
579
-
580
- result = sch_ruleset
581
- return result
582
- end
583
-
584
- def self.addScheduleTypeLimits(model) # TODO: - make sure to add this new method to cofee when done
585
- type_limits = {}
586
-
587
- lightsScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
588
- lightsScheduleTypeLimits.setName('Lights Schedule Type Limits')
589
- lightsScheduleTypeLimits.setLowerLimitValue(0.0)
590
- lightsScheduleTypeLimits.setUpperLimitValue(1.0)
591
- lightsScheduleTypeLimits.setNumericType('Continuous')
592
- lightsScheduleTypeLimits.setUnitType('Dimensionless')
593
- type_limits['Lights'] = lightsScheduleTypeLimits
594
-
595
- occupancyScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
596
- occupancyScheduleTypeLimits.setName('Occupancy Schedule Type Limits')
597
- occupancyScheduleTypeLimits.setLowerLimitValue(0.0)
598
- occupancyScheduleTypeLimits.setUpperLimitValue(1.0)
599
- occupancyScheduleTypeLimits.setNumericType('Continuous')
600
- occupancyScheduleTypeLimits.setUnitType('Dimensionless')
601
- type_limits['Occupancy'] = occupancyScheduleTypeLimits
602
-
603
- peopleActivityScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
604
- peopleActivityScheduleTypeLimits.setName('People Activity Type Limits')
605
- peopleActivityScheduleTypeLimits.setLowerLimitValue(0.0)
606
- # peopleActivityScheduleTypeLimits.setUpperLimitValue(1500.0)
607
- peopleActivityScheduleTypeLimits.setNumericType('Continuous')
608
- peopleActivityScheduleTypeLimits.setUnitType('ActivityLevel')
609
- type_limits['People Activity'] = peopleActivityScheduleTypeLimits
610
-
611
- equipmentScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
612
- equipmentScheduleTypeLimits.setName('Equipment Schedule Type Limits')
613
- equipmentScheduleTypeLimits.setLowerLimitValue(0.0)
614
- equipmentScheduleTypeLimits.setUpperLimitValue(1.0)
615
- equipmentScheduleTypeLimits.setNumericType('Continuous')
616
- equipmentScheduleTypeLimits.setUnitType('Dimensionless')
617
- type_limits['Equipment'] = equipmentScheduleTypeLimits
618
-
619
- waterUseScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
620
- waterUseScheduleTypeLimits.setName('Water Use Schedule Type Limits')
621
- waterUseScheduleTypeLimits.setLowerLimitValue(0.0)
622
- waterUseScheduleTypeLimits.setUpperLimitValue(1.0)
623
- waterUseScheduleTypeLimits.setNumericType('Continuous')
624
- waterUseScheduleTypeLimits.setUnitType('Dimensionless')
625
- type_limits['Water Use'] = waterUseScheduleTypeLimits
626
-
627
- elevatorsScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
628
- elevatorsScheduleTypeLimits.setName('Elevators Schedule Type Limits')
629
- elevatorsScheduleTypeLimits.setLowerLimitValue(0.0)
630
- elevatorsScheduleTypeLimits.setUpperLimitValue(1.0)
631
- elevatorsScheduleTypeLimits.setNumericType('Continuous')
632
- elevatorsScheduleTypeLimits.setUnitType('Dimensionless')
633
- type_limits['Elevators'] = elevatorsScheduleTypeLimits
634
-
635
- processLoadsScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
636
- processLoadsScheduleTypeLimits.setName('Process Loads Schedule Type Limits')
637
- processLoadsScheduleTypeLimits.setLowerLimitValue(0.0)
638
- processLoadsScheduleTypeLimits.setUpperLimitValue(1.0)
639
- processLoadsScheduleTypeLimits.setNumericType('Continuous')
640
- processLoadsScheduleTypeLimits.setUnitType('Dimensionless')
641
- type_limits['Process Load'] = elevatorsScheduleTypeLimits
642
-
643
- thermostatHeatingScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
644
- thermostatHeatingScheduleTypeLimits.setName('Thermostat Heating Setpoint Schedule Type Limits')
645
- thermostatHeatingScheduleTypeLimits.setLowerLimitValue(0.0)
646
- thermostatHeatingScheduleTypeLimits.setUpperLimitValue(100.0)
647
- thermostatHeatingScheduleTypeLimits.setNumericType('Continuous')
648
- thermostatHeatingScheduleTypeLimits.setUnitType('Temperature')
649
- type_limits['Thermostat Heating Setpoint'] = thermostatHeatingScheduleTypeLimits
650
-
651
- temperatureScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
652
- temperatureScheduleTypeLimits.setName('Thermostat Cooling Setpoint Schedule Type Limits')
653
- temperatureScheduleTypeLimits.setLowerLimitValue(0.0)
654
- temperatureScheduleTypeLimits.setUpperLimitValue(100.0)
655
- temperatureScheduleTypeLimits.setNumericType('Continuous')
656
- temperatureScheduleTypeLimits.setUnitType('Temperature')
657
- type_limits['Thermostat Cooling Setpoint'] = temperatureScheduleTypeLimits
658
-
659
- hvacOperationScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
660
- hvacOperationScheduleTypeLimits.setName('HVAC Operation Schedule Type Limits')
661
- hvacOperationScheduleTypeLimits.setLowerLimitValue(0)
662
- hvacOperationScheduleTypeLimits.setUpperLimitValue(1)
663
- hvacOperationScheduleTypeLimits.setNumericType('Discrete')
664
- hvacOperationScheduleTypeLimits.setUnitType('Availability')
665
- type_limits['HVAC Operation'] = hvacOperationScheduleTypeLimits
666
-
667
- temperatureScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
668
- temperatureScheduleTypeLimits.setName('Temperature Schedule Type Limits')
669
- temperatureScheduleTypeLimits.setNumericType('Continuous')
670
- temperatureScheduleTypeLimits.setUnitType('Temperature')
671
- type_limits['Temperature'] = temperatureScheduleTypeLimits
672
-
673
- fractionScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
674
- fractionScheduleTypeLimits.setName('Fraction Schedule Type Limits')
675
- fractionScheduleTypeLimits.setLowerLimitValue(0.0)
676
- fractionScheduleTypeLimits.setUpperLimitValue(1.0)
677
- fractionScheduleTypeLimits.setNumericType('Continuous')
678
- fractionScheduleTypeLimits.setUnitType('Dimensionless')
679
- type_limits['Fraction'] = fractionScheduleTypeLimits
680
-
681
- dimensionlessScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
682
- dimensionlessScheduleTypeLimits.setName('Dimensionless Schedule Type Limits')
683
- dimensionlessScheduleTypeLimits.setNumericType('Continuous')
684
- dimensionlessScheduleTypeLimits.setUnitType('Dimensionless')
685
- type_limits['Dimensionless'] = dimensionlessScheduleTypeLimits
686
-
687
- return type_limits
688
- end
689
-
690
- # create TimeSeries from ScheduleRuleset
691
- def self.create_timeseries_from_schedule_ruleset(model, schedule_ruleset)
692
- yd = model.getYearDescription
693
- start_date = yd.makeDate(1, 1)
694
- end_date = yd.makeDate(12, 31)
695
-
696
- values = OpenStudio::DoubleVector.new
697
- day = OpenStudio::Time.new(1.0)
698
- interval = OpenStudio::Time.new(1.0 / 48.0)
699
- day_schedules = schedule_ruleset.to_ScheduleRuleset.get.getDaySchedules(start_date, end_date)
700
- day_schedules.each do |day_schedule|
701
- time = interval
702
- while time < day
703
- values << day_schedule.getValue(time)
704
- time += interval
705
- end
706
- end
707
- time_series = OpenStudio::TimeSeries.new(start_date, interval, OpenStudio.createVector(values), '')
708
- end
709
-
710
- # create ScheduleVariableInterval from TimeSeries
711
- def self.create_schedule_variable_interval_from_time_series(model, time_series)
712
- result = OpenStudio::Model::ScheduleInterval.fromTimeSeries(time_series, model).get
713
- end
714
-
715
- def self.adjust_hours_of_operation_for_schedule_ruleset(runner, model, schedule, options = {})
716
- defaults = {
717
- 'base_start_hoo' => 8.0, # may not be good idea to have default
718
- 'base_finish_hoo' => 18.0, # may not be good idea to have default
719
- 'delta_length_hoo' => 0.0,
720
- 'shift_hoo' => 0.0,
721
- 'default' => true,
722
- 'mon' => true,
723
- 'tue' => true,
724
- 'wed' => true,
725
- 'thur' => true,
726
- 'fri' => true,
727
- 'sat' => true,
728
- 'sun' => true,
729
- 'summer' => false,
730
- 'winter' => false
731
- }
732
-
733
- # merge user inputs with defaults
734
- options = defaults.merge(options)
735
-
736
- # grab schedule out of argument
737
- if schedule.to_ScheduleRuleset.is_initialized
738
- schedule = schedule.to_ScheduleRuleset.get
739
- else
740
- runner.registerWarning("you should only pass ruleset schedules into this method. skipping #{schedule.name}")
741
- return nil
742
- end
743
-
744
- # array of all profiles to change
745
- profiles = []
746
-
747
- # push default profiles to array
748
- if options['default']
749
- default_rule = schedule.defaultDaySchedule
750
- profiles << default_rule
751
- end
752
-
753
- # push profiles to array
754
- rules = schedule.scheduleRules
755
- rules.each do |rule|
756
- day_sch = rule.daySchedule
757
-
758
- # if any day requested also exists in the rule, then it will be altered
759
- alter_rule = false
760
- if rule.applyMonday && rule.applyMonday == options['mon'] then alter_rule = true end
761
- if rule.applyTuesday && rule.applyTuesday == options['tue'] then alter_rule = true end
762
- if rule.applyWednesday && rule.applyWednesday == options['wed'] then alter_rule = true end
763
- if rule.applyThursday && rule.applyThursday == options['thur'] then alter_rule = true end
764
- if rule.applyFriday && rule.applyFriday == options['fri'] then alter_rule = true end
765
- if rule.applySaturday && rule.applySaturday == options['sat'] then alter_rule = true end
766
- if rule.applySunday && rule.applySunday == options['sun'] then alter_rule = true end
767
-
768
- # TODO: - add in logic to warn user about conflicts where a single rule has conflicting tests
769
-
770
- if alter_rule
771
- profiles << day_sch
772
- end
773
- end
774
-
775
- # add design days to array
776
- if options['summer']
777
- summer_design = schedule.summerDesignDaySchedule
778
- profiles << summer_design
779
- end
780
- if options['winter']
781
- winter_design = schedule.winterDesignDaySchedule
782
- profiles << winter_design
783
- end
784
-
785
- # give info messages as I change specific profiles
786
- runner.registerInfo("Adjusting #{schedule.name}")
787
-
788
- # rename schedule
789
- schedule.setName("#{schedule.name} - extend #{options['delta_length_hoo']} shift #{options['shift_hoo']}") # if I put inputs here name will get long
790
-
791
- # break time args into hours and minutes
792
- start_hoo_hours = (options['base_start_hoo']).to_i
793
- start_hoo_minutes = (((options['base_start_hoo']) - (options['base_start_hoo']).to_i) * 60).to_i
794
- finish_hoo_hours = (options['base_finish_hoo']).to_i
795
- finish_hoo_minutes = (((options['base_finish_hoo']) - (options['base_finish_hoo']).to_i) * 60).to_i
796
- delta_hours = (options['delta_length_hoo']).to_i
797
- delta_minutes = (((options['delta_length_hoo']) - (options['delta_length_hoo']).to_i) * 60).to_i
798
- shift_hours = (options['shift_hoo']).to_i
799
- shift_minutes = (((options['shift_hoo']) - (options['shift_hoo']).to_i) * 60).to_i
800
-
801
- # time objects to use in measure
802
- time_0 = OpenStudio::Time.new(0, 0, 0, 0)
803
- time_1_min = OpenStudio::Time.new(0, 0, 1, 0) # add this to avoid times in day profile less than this
804
- time_12 = OpenStudio::Time.new(0, 12, 0, 0)
805
- time_24 = OpenStudio::Time.new(0, 24, 0, 0)
806
- start_hoo_time = OpenStudio::Time.new(0, start_hoo_hours, start_hoo_minutes, 0)
807
- finish_hoo_time = OpenStudio::Time.new(0, finish_hoo_hours, finish_hoo_minutes, 0)
808
- delta_time = OpenStudio::Time.new(0, delta_hours, delta_minutes, 0) # not used
809
- shift_time = OpenStudio::Time.new(0, shift_hours, shift_minutes, 0)
810
-
811
- # calculations
812
- if options['base_start_hoo'] <= options['base_finish_hoo']
813
- base_opp_day_length = options['base_finish_hoo'] - options['base_start_hoo']
814
- mid_hoo = start_hoo_time + (finish_hoo_time - start_hoo_time) / 2
815
- mid_non_hoo = mid_hoo + time_12
816
- if mid_non_hoo > time_24 then mid_non_hoo -= time_24 end
817
- else
818
- base_opp_day_length = options['base_finish_hoo'] - options['base_start_hoo'] + 24
819
- mid_non_hoo = finish_hoo_time + (start_hoo_time - finish_hoo_time) / 2
820
- mid_hoo = mid_non_hoo + time_12
821
- if mid_non_hoo > time_24 then mid_non_hoo -= time_24 end
822
- end
823
- adjusted_opp_day_length = base_opp_day_length + options['delta_length_hoo']
824
- hoo_time_multiplier = adjusted_opp_day_length / base_opp_day_length
825
- non_hoo_time_multiplier = (24 - adjusted_opp_day_length) / (24 - base_opp_day_length)
826
-
827
- # check for invalid input
828
- if adjusted_opp_day_length < 0
829
- runner.registerError('Requested hours of operation adjustment results in an invalid negative hours of operation')
830
- return false
831
- end
832
- # check for invalid input
833
- if adjusted_opp_day_length > 24
834
- runner.registerError('Requested hours of operation adjustment results in more than 24 hours of operation')
835
- return false
836
- end
837
-
838
- # making some temp objects to avoid having to deal with wrap around for change of hoo times
839
- mid_hoo < start_hoo_time ? (adj_mid_hoo = mid_hoo + time_24) : (adj_mid_hoo = mid_hoo)
840
- finish_hoo_time < adj_mid_hoo ? (adj_finish_hoo_time = finish_hoo_time + time_24) : (adj_finish_hoo_time = finish_hoo_time)
841
- mid_non_hoo < adj_finish_hoo_time ? (adj_mid_non_hoo = mid_non_hoo + time_24) : (adj_mid_non_hoo = mid_non_hoo)
842
- adj_start = start_hoo_time + time_24 # not used
843
-
844
- # edit profiles
845
- profiles.each do |day_sch|
846
- times = day_sch.times
847
- values = day_sch.values
848
-
849
- # in this case delete all values outside of
850
- # todo - may need similar logic if exactly 0 hours
851
- if adjusted_opp_day_length == 24
852
- start_val = day_sch.getValue(start_hoo_time)
853
- finish_val = day_sch.getValue(finish_hoo_time)
854
-
855
- # remove times out of range that should not be reference or compressed
856
- if start_hoo_time < finish_hoo_time
857
- times.each do |time|
858
- if time <= start_hoo_time || time > finish_hoo_time
859
- day_sch.removeValue(time)
860
- end
861
- end
862
- # add in values
863
- day_sch.addValue(start_hoo_time, start_val)
864
- day_sch.addValue(finish_hoo_time, finish_val)
865
- day_sch.addValue(time_24, [start_val, finish_val].max)
866
- else
867
- times.each do |time|
868
- if time > start_hoo_time && time <= finish_hoo_time
869
- day_sch.removeValue(time)
870
- end
871
- end
872
- # add in values
873
- day_sch.addValue(finish_hoo_time, finish_val)
874
- day_sch.addValue(start_hoo_time, start_val)
875
- day_sch.addValue(time_24, [values.first, values.last].max)
876
- end
877
-
878
- end
879
-
880
- times = day_sch.times
881
- values = day_sch.values
882
-
883
- # arrays for values to avoid overlap conflict of times
884
- new_times = []
885
- new_values = []
886
-
887
- # this is to store what datapoint will be first after midnight, and what the value at that time should be
888
- min_time_new = time_24
889
- min_time_value = nil
890
-
891
- # flag if found time at 24
892
- found_24_or_0 = false
893
-
894
- # push times to array
895
- times.each do |time|
896
- # create logic for four possible quadrants. Assume any quadrant can pass over 24/0 threshold
897
- time < start_hoo_time ? (temp_time = time + time_24) : (temp_time = time)
898
-
899
- # calculate change in time do to hoo delta
900
- if temp_time <= adj_finish_hoo_time
901
- expand_time = (temp_time - adj_mid_hoo) * hoo_time_multiplier - (temp_time - adj_mid_hoo)
902
- else
903
- expand_time = (temp_time - adj_mid_non_hoo) * non_hoo_time_multiplier - (temp_time - adj_mid_non_hoo)
904
- end
905
-
906
- new_time = time + shift_time + expand_time
907
-
908
- # adjust wrap around times
909
- if new_time < time_0
910
- new_time += time_24
911
- elsif new_time > time_24
912
- new_time -= time_24
913
- end
914
- new_times << new_time
915
-
916
- # see which new_time has the lowest value. Then add a value at 24 equal to that
917
- if !found_24_or_0 && new_time <= min_time_new
918
- min_time_new = new_time
919
- min_time_value = day_sch.getValue(time)
920
- elsif new_time == time_24 # this was added to address time exactly at 24
921
- min_time_new = new_time
922
- min_time_value = day_sch.getValue(time)
923
- found_24_or_0 = true
924
- elsif new_time == time_0
925
- min_time_new = new_time
926
- min_time_value = day_sch.getValue(time_0)
927
- found_24_or_0 = true
928
- end
929
- end
930
-
931
- # push values to array
932
- values.each do |value|
933
- new_values << value
934
- end
935
-
936
- # add value for what will be 24
937
- new_times << time_24
938
- new_values << min_time_value
939
-
940
- new_time_val_hash = {}
941
- new_times.each_with_index do |time, i|
942
- new_time_val_hash[time.totalHours] = { time: time, value: new_values[i] }
943
- end
944
-
945
- # clear values
946
- day_sch.clearValues
947
-
948
- new_time_val_hash = Hash[new_time_val_hash.sort]
949
- prev_time = nil
950
- new_time_val_hash.sort.each do |hours, time_val|
951
- if prev_time.nil? || time_val[:time] - prev_time > time_1_min
952
- day_sch.addValue(time_val[:time], time_val[:value])
953
- prev_time = time_val[:time]
954
- else
955
- puts "time step in #{day_sch.name} between #{prev_time.toString} and #{time_val[:time].toString} is too small to support, not adding value"
956
- end
957
- end
958
- end
959
-
960
- return schedule
961
- end
962
- end