Class: ShiftHoursOfOperation
- Inherits:
-
OpenStudio::Measure::ModelMeasure
- Object
- OpenStudio::Measure::ModelMeasure
- ShiftHoursOfOperation
- Defined in:
- lib/measures/shift_hours_of_operation/measure.rb
Overview
start the measure
Instance Method Summary collapse
-
#arguments(model) ⇒ Object
define the arguments that the user will input.
-
#description ⇒ Object
human readable description.
-
#hoo_summary(model, runner, standard) ⇒ Object
get model hoo info.
-
#modeler_description ⇒ Object
human readable description of modeling approach.
-
#name ⇒ Object
human readable name.
-
#process_hoo(used_hoo_sch_sets, model, runner, args, days_of_week, hoo_start_dows, hoo_dur_dows) ⇒ Object
process hoo schedules for various days of the week todo - when date range arg is used and not full year will never want to change default profile.
-
#run(model, runner, user_arguments) ⇒ Object
define what happens when the measure is run.
Instance Method Details
#arguments(model) ⇒ Object
define the arguments that the user will input
33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 |
# File 'lib/measures/shift_hours_of_operation/measure.rb', line 33 def arguments(model) args = OpenStudio::Measure::OSArgumentVector.new # delta hoo_start for weekdays hoo_start_weekday = OpenStudio::Measure::OSArgument.makeDoubleArgument('hoo_start_weekday', true) hoo_start_weekday.setDisplayName('Shift the weekday start of hours of operation.') hoo_start_weekday.setDescription('Use decimal hours so an 1 hour and 15 minute shift would be 1.25. Positive value moves the hour of operation later') hoo_start_weekday.setDefaultValue(0.0) hoo_start_weekday.setUnits('Hours') hoo_start_weekday.setMinValue(-24.0) hoo_start_weekday.setMaxValue(24.0) args << hoo_start_weekday # delta hoo_dur for weekday hoo_dur_weekday = OpenStudio::Measure::OSArgument.makeDoubleArgument('hoo_dur_weekday', true) hoo_dur_weekday.setDisplayName('Extend the weekday of hours of operation.') hoo_dur_weekday.setDescription('Use decimal hours so an 1 hour and 15 minute would be 1.25. Positive value makes the hour of operation longer.') hoo_dur_weekday.setDefaultValue(0.0) hoo_dur_weekday.setUnits('Hours') hoo_dur_weekday.setMinValue(-24.0) hoo_dur_weekday.setMaxValue(24.0) args << hoo_dur_weekday # TODO: - could include every day of the week # delta hoo_start for saturdays hoo_start_saturday = OpenStudio::Measure::OSArgument.makeDoubleArgument('hoo_start_saturday', true) hoo_start_saturday.setDisplayName('Shift the saturday start of hours of operation.') hoo_start_saturday.setDescription('Use decimal hours so an 1 hour and 15 minute shift would be 1.25. Positive value moves the hour of operation later') hoo_start_saturday.setDefaultValue(0.0) hoo_start_saturday.setUnits('Hours') hoo_start_saturday.setMinValue(-24.0) hoo_start_saturday.setMaxValue(24.0) args << hoo_start_saturday # delta hoo_dur for saturday hoo_dur_saturday = OpenStudio::Measure::OSArgument.makeDoubleArgument('hoo_dur_saturday', true) hoo_dur_saturday.setDisplayName('Extend the saturday of hours of operation.') hoo_dur_saturday.setDescription('Use decimal hours so an 1 hour and 15 minute would be 1.25. Positive value makes the hour of operation longer.') hoo_dur_saturday.setDefaultValue(0.0) hoo_dur_saturday.setUnits('Hours') hoo_dur_saturday.setMinValue(-24.0) hoo_dur_saturday.setMaxValue(24.0) args << hoo_dur_saturday # delta hoo_start for sundays hoo_start_sunday = OpenStudio::Measure::OSArgument.makeDoubleArgument('hoo_start_sunday', true) hoo_start_sunday.setDisplayName('Shift the sunday start of hours of operation.') hoo_start_sunday.setDescription('Use decimal hours so an 1 hour and 15 minute shift would be 1.25. Positive value moves the hour of operation later') hoo_start_sunday.setDefaultValue(0.0) hoo_start_sunday.setUnits('Hours') hoo_start_sunday.setMinValue(-24.0) hoo_start_sunday.setMaxValue(24.0) args << hoo_start_sunday # delta hoo_dur for sunday hoo_dur_sunday = OpenStudio::Measure::OSArgument.makeDoubleArgument('hoo_dur_sunday', true) hoo_dur_sunday.setDisplayName('Extend the sunday of hours of operation.') hoo_dur_sunday.setDescription('Use decimal hours so an 1 hour and 15 minute would be 1.25. Positive value makes the hour of operation longer.') hoo_dur_sunday.setDefaultValue(0.0) hoo_dur_sunday.setUnits('Hours') hoo_dur_sunday.setMinValue(-24.0) hoo_dur_sunday.setMaxValue(24.0) args << hoo_dur_sunday # TODO: - could include start and end days to have delta or absolute values applied to. (maybe decimal between 1.0 and 13.0 month where 3.50 would be March 15th) # make an argument for delta_values delta_values = OpenStudio::Measure::OSArgument.makeBoolArgument('delta_values', true) delta_values.setDisplayName('Hours of operation values treated as deltas') delta_values.setDescription('When this is true the hours of operation start and duration represent a delta from the original model values. When switched to false they represent absolute values.') delta_values.setDefaultValue(true) args << delta_values # make an argument for infer_parametric_schedules infer_parametric_schedules = OpenStudio::Measure::OSArgument.makeBoolArgument('infer_parametric_schedules', true) infer_parametric_schedules.setDisplayName('Dynamically generate parametric schedules from current ruleset schedules.') infer_parametric_schedules.setDescription('When this is true the parametric schedule formulas and hours of operation will be generated from the existing model schedules. When false it expects the model already has parametric formulas stored.') infer_parametric_schedules.setDefaultValue(true) args << infer_parametric_schedules # delta hoo_start for sundays fraction_of_daily_occ_range = OpenStudio::Measure::OSArgument.makeDoubleArgument('fraction_of_daily_occ_range', true) fraction_of_daily_occ_range.setDisplayName('Fraction of Daily Occupancy Range.') fraction_of_daily_occ_range.setDescription('This determine what fraction of occupancy be considered operating conditions. This fraction is normalized to expanded to range seen over the full year and does not necessary equal fraction of design occupancy. This value should be between 0 and 1.0 and is only used if dynamically generated parametric schedules are used.') fraction_of_daily_occ_range.setDefaultValue(0.25) fraction_of_daily_occ_range.setUnits('Hours') fraction_of_daily_occ_range.setMinValue(0.0) fraction_of_daily_occ_range.setMaxValue(1.0) args << fraction_of_daily_occ_range # argument to choose hour of operation variable method choices = OpenStudio::StringVector.new choices << 'fractional' choices << 'hours' hoo_var_method = OpenStudio::Measure::OSArgument.makeChoiceArgument('hoo_var_method', choices, true) hoo_var_method.setDisplayName('Hours of Operation Variable Method for Scheudle Profile Formula.') hoo_var_method.setDescription('If dynamically generate parametric schedules from current ruleset scheudles is selected ,this argument is used to determine if the schedule profile formulas define time of points in a profile as a a specific delta from the star, middle, or end of the horus of operation, or if the delta is fractaionl percentate of the horus fo operation ro non-operation/vacant time.') hoo_var_method.setDefaultValue('fractional') args << hoo_var_method # make an argument for target_hoo_from_model # Should only be true when infer_parametric_schedules is false target_hoo_from_model = OpenStudio::Measure::OSArgument.makeBoolArgument('target_hoo_from_model', true) target_hoo_from_model.setDisplayName('Use model hours of operation as target') target_hoo_from_model.setDescription('The default behavior is for this to be false. This can not be used unless Dynamically generate parametric schedules from current ruleset schedules is set to false and if the schedules in the model already have parametric profiles. When changed to true all of the hours of operation start and duration values will be ignored as the bool to treat those values as relative or absolute. Instead the hours of operation schedules for the model will be used.') target_hoo_from_model.setDefaultValue(false) args << target_hoo_from_model # TODO: - add argument for step frequency, which is hours per step (should be fractional 1 or less generally). # For now it defaults to simulation timestep return args end |
#description ⇒ Object
human readable description
23 24 25 |
# File 'lib/measures/shift_hours_of_operation/measure.rb', line 23 def description return 'This measure will infer the hours of operation for the building and then will shift the start of the hours of operation and change the duration of the hours of operation. In an alternate workflow you can directly pass in target start and duration rather than a shift and delta. Inputs can vary for weekday, Saturday, and Sunday. if a day does not have any hours of operation to start with increasing hours of operation may not have any impact as the auto generated data may not know what to do during operating hours. Future version may be able to borrow a profile formula but would probably require additional user arguments.' end |
#hoo_summary(model, runner, standard) ⇒ Object
get model hoo info
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/measures/shift_hours_of_operation/measure.rb', line 149 def hoo_summary(model, runner, standard) hoo_summary_hash = {} hoo_summary_hash[:zero_hoo] = [] hoo_summary_hash[:final_hoo_start_range] = [] hoo_summary_hash[:final_hoo_dur_range] = [] model.getSpaces.sort.each do |space| default_sch_type = OpenStudio::Model::DefaultScheduleType.new('HoursofOperationSchedule') hours_of_operation = space.getDefaultSchedule(default_sch_type) if !hours_of_operation.is_initialized runner.registerWarning("Hours of Operation Schedule is not set for #{space.name}.") next end hours_of_operation_hash = OpenstudioStandards::Space.space_hours_of_operation(space) hours_of_operation_hash.each do |hoo_key, val| if val[:hoo_hours] == 0.0 hoo_summary_hash[:zero_hoo] << val[:hoo_hours] else hoo_summary_hash[:final_hoo_dur_range] << val[:hoo_hours] hoo_summary_hash[:final_hoo_start_range] << val[:hoo_start] end end end return hoo_summary_hash end |
#modeler_description ⇒ Object
human readable description of modeling approach
28 29 30 |
# File 'lib/measures/shift_hours_of_operation/measure.rb', line 28 def modeler_description return 'This will only impact schedule rulesets. It will use methods in openstudio-standards to infer hours of operation, develop a parametric formula for all of the ruleset schedules, alter the hours of operation inputs to that formula and then re-apply the schedules. Input is expose to set ramp frequency of the resulting schedules. If inputs are such that no changes are requested, bypass the measure with NA so that it will not be parameterized. An advanced option for this measure would be bool to use hours of operation from OSM schedule ruleset hours of operation instead of inferring from standards. This should allow different parts of the building to have different hours of operation in the seed model.' end |
#name ⇒ Object
human readable name
17 18 19 20 |
# File 'lib/measures/shift_hours_of_operation/measure.rb', line 17 def name # Measure name should be the title case of the class name. return 'Shift Hours of Operation' end |
#process_hoo(used_hoo_sch_sets, model, runner, args, days_of_week, hoo_start_dows, hoo_dur_dows) ⇒ Object
process hoo schedules for various days of the week todo - when date range arg is used and not full year will never want to change default profile
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 |
# File 'lib/measures/shift_hours_of_operation/measure.rb', line 177 def process_hoo(used_hoo_sch_sets, model, runner, args, days_of_week, hoo_start_dows, hoo_dur_dows) # profiles added to this will be processed altered_schedule_days = {} # key is profile value is original index position defined in used_hoo_sch_sets # loop through horus of operation schedules used_hoo_sch_sets.uniq.each do |hoo_sch, hours_of_operation_hash| if !hoo_sch.to_ScheduleRuleset.is_initialized runner.registerWarning("#{hoo_sch.name} is not schedule schedule ruleset, will not be altered by this method.") next end hoo_sch = hoo_sch.to_ScheduleRuleset.get year_description = hoo_sch.model.yearDescription.get year = year_description.assumedYear year_start_date = OpenStudio::Date.new(OpenStudio::MonthOfYear.new('January'), 1, year) year_end_date = OpenStudio::Date.new(OpenStudio::MonthOfYear.new('December'), 31, year) orig_profile_indexes_used = hoo_sch.getActiveRuleIndices(year_start_date, year_end_date) orig_num_days_default_used = orig_profile_indexes_used.count(-1) if orig_num_days_default_used > 0 default_prof = hoo_sch.defaultDaySchedule # clone default profile as rule that sits above it so it can be evauluated and used if needed new_prof = default_prof.clone(model).to_ScheduleDay.get new_rule = OpenStudio::Model::ScheduleRule.new(hoo_sch, new_prof) hoo_sch.setScheduleRuleIndex(new_rule, hoo_sch.scheduleRules.size - 1) # set days of week for clone to match days of week passed into the method if days_of_week.include?('mon') new_rule.setApplyMonday(true) end if days_of_week.include?('tue') new_rule.setApplyTuesday(true) end if days_of_week.include?('wed') new_rule.setApplyWednesday(true) end if days_of_week.include?('thur') new_rule.setApplyThursday(true) end if days_of_week.include?('fri') new_rule.setApplyFriday(true) end if days_of_week.include?('sat') new_rule.setApplySaturday(true) end if days_of_week.include?('sun') new_rule.setApplySunday(true) end # check if default days are used at all profile_indexes_used = hoo_sch.getActiveRuleIndices(year_start_date, year_end_date) num_days_new_profile_used = profile_indexes_used.count(hoo_sch.scheduleRules.size - 1) if !profile_indexes_used.uniq.include?(-1) && num_days_new_profile_used > 0 # don't need new profile, can use default new_rule.remove altered_schedule_days[hoo_sch.defaultDaySchedule] = -1 elsif num_days_new_profile_used == 0.0 # can remove cloned rule and skip the default profile (don't pass into array) new_rule.remove else altered_schedule_days[new_rule.daySchedule] = -1 # use hoo that was applicable to the default before it was cloned end end # use this to link to hoo from hours_of_operation_hash counter_of_orig_index = hours_of_operation_hash.size - 2 # this is not impacted by cloning that may have happened above hoo_sch.scheduleRules.reverse_each do |rule| # inspect days of the week actual_days_of_week_for_profile = [] if rule.applyMonday then actual_days_of_week_for_profile << 'mon' end if rule.applyTuesday then actual_days_of_week_for_profile << 'tue' end if rule.applyWednesday then actual_days_of_week_for_profile << 'wed' end if rule.applyThursday then actual_days_of_week_for_profile << 'thur' end if rule.applyFriday then actual_days_of_week_for_profile << 'fri' end if rule.applySaturday then actual_days_of_week_for_profile << 'sat' end if rule.applySunday then actual_days_of_week_for_profile << 'sun' end # if an exact match for the rules passed in are met, this rule can be edited in place (update later for date range) day_of_week_intersect = days_of_week & actual_days_of_week_for_profile current_rule_index = rule.ruleIndex if days_of_week == actual_days_of_week_for_profile altered_schedule_days[rule.daySchedule] = counter_of_orig_index # if this rule contains the requested days of the week and another then a clone should be made above this with only the requested days of the week that are also already on for this rule elsif !day_of_week_intersect.empty? # clone default profile as rule that sits above it so it can be evaluated and used if needed new_rule = rule.clone(model).to_ScheduleRule.get hoo_sch.setScheduleRuleIndex(new_rule, current_rule_index) # the cloned rule should be just above what was cloned # update days of week for rule if day_of_week_intersect.include?('mon') new_rule.setApplyMonday(true) else new_rule.setApplyMonday(false) end if day_of_week_intersect.include?('tue') new_rule.setApplyTuesday(true) else new_rule.setApplyTuesday(false) end if day_of_week_intersect.include?('wed') new_rule.setApplyWednesday(true) else new_rule.setApplyWednesday(false) end if day_of_week_intersect.include?('thur') new_rule.setApplyThursday(true) else new_rule.setApplyThursday(false) end if day_of_week_intersect.include?('fri') new_rule.setApplyFriday(true) else new_rule.setApplyFriday(false) end if day_of_week_intersect.include?('sat') new_rule.setApplySaturday(true) else new_rule.setApplySaturday(false) end if day_of_week_intersect.include?('sun') new_rule.setApplySunday(true) else new_rule.setApplySunday(false) end # add to array altered_schedule_days[new_rule.daySchedule] = counter_of_orig_index end # adjust the count used to find hoo from hours_of_operation_hash counter_of_orig_index -= 1 end runner.registerInfo("For #{hoo_sch.name} #{days_of_week.inspect} #{altered_schedule_days.size} profiles will be processed.") # convert altered_schedule_days to hash where key is profile and value is key of index in hours_of_operation_hash # loop through profiles to changes altered_schedule_days.each do |new_profile, hoo_hash_index| # gather info and edit selected profile if args['delta_values'] orig_hoo_start = hours_of_operation_hash[hoo_hash_index][:hoo_start] orig_hoo_dur = hours_of_operation_hash[hoo_hash_index][:hoo_hours] # check for duration grater than 24 or lower than 0 max_dur_delta = 24 - orig_hoo_dur min_dur_delta = orig_hoo_dur * -1.0 if hoo_dur_dows > max_dur_delta target_dur = 24.0 runner.registerWarning("For profile in #{hoo_sch.name} duration is being capped at 24 hours.") elsif hoo_dur_dows < min_dur_delta target_dur = 0.0 runner.registerWarning("For profile in #{hoo_sch.name} duration is being limited to a low of 0 hours.") else target_dur = hoo_dur_dows + orig_hoo_dur end # setup new hoo values with delta if orig_hoo_start + hoo_start_dows <= 24.0 new_hoo_start = orig_hoo_start + hoo_start_dows else new_hoo_start = orig_hoo_start + hoo_start_dows - 24.0 end if new_hoo_start + hoo_dur_dows + orig_hoo_dur <= 24.0 new_hoo_end = new_hoo_start + target_dur else new_hoo_end = new_hoo_start + target_dur - 24.0 end else new_hoo_start = hoo_start_dows target_dur = hoo_dur_dows if new_hoo_start + target_dur < 24.0 new_hoo_end = new_hoo_start + target_dur elsif new_hoo_start + target_dur == 24.0 new_hoo_end = 0.0 else # greater than 24 new_hoo_end = new_hoo_start + target_dur - 24.0 end end # setup hoo start time target_start_hr = new_hoo_start.truncate target_start_min = ((new_hoo_start - target_start_hr) * 60.0).truncate target_start_time = OpenStudio::Time.new(0, target_start_hr, target_start_min, 0) # setup hoo end time target_end_hr = new_hoo_end.truncate target_end_min = ((new_hoo_end - target_end_hr) * 60.0).truncate target_end_time = OpenStudio::Time.new(0, target_end_hr, target_end_min, 0) # adding new values new_profile.clearValues if target_dur < 24 new_profile.addValue(target_start_time, 0) end if target_dur > 0 new_profile.addValue(target_end_time, 1) end os_time_24 = OpenStudio::Time.new(0, 24, 0, 0) if target_end_time > target_start_time || target_start_time == os_time_24 new_profile.addValue(os_time_24, 0) elsif target_end_time < target_start_time new_profile.addValue(os_time_24, 1) else # they are equal if target_dur == 24.0 new_profile.addValue(os_time_24, 1) else new_profile.addValue(os_time_24, 0) end end end end return altered_schedule_days end |
#run(model, runner, user_arguments) ⇒ Object
define what happens when the measure is run
397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 |
# File 'lib/measures/shift_hours_of_operation/measure.rb', line 397 def run(model, runner, user_arguments) super(model, runner, user_arguments) # assign the user inputs to variables args = runner.getArgumentValues(arguments(model), user_arguments) args = Hash[args.collect{ |k, v| [k.to_s, v] }] if !args then return false end # open channel to log messages reset_log # Turn debugging output on/off debug = false # load standards standard = Standard.build('90.1-2004') # selected template doesn't matter if args['infer_parametric_schedules'] # infer hours of operation for the building # @param fraction_of_daily_occ_range [Double] fraction above/below daily min range required to start and end hours of operation occ_fraction = args['fraction_of_daily_occ_range'] OpenstudioStandards::Schedules.model_infer_hours_of_operation_building(model, fraction_of_daily_occ_range: occ_fraction, gen_occ_profile: true) runner.registerInfo('Inferring initial hours of operation for the building and generating parametric profile formulas.') # report back hours of operation initial_hoo_range = [] hours_of_operation_hash_test = OpenstudioStandards::Space.space_hours_of_operation(model.getSpaces.first) hours_of_operation_hash_test.each do |hoo_key, val| initial_hoo_range << val[:hoo_hours] runner.registerInfo("For Profile Index #{hoo_key} hours of operation run for #{val[:hoo_hours]} hours, from #{val[:hoo_start]} to #{val[:hoo_end]} and is used for #{val[:days_used].size} days of the year.") end # model_setup_parametric_schedules OpenstudioStandards::Schedules.model_setup_parametric_schedules(model, gather_data_only: false, hoo_var_method: args['hoo_var_method']) end # report initial condition of model hoo_summary_hash = hoo_summary(model, runner, standard) if !hoo_summary_hash[:zero_hoo].empty? runner.registerInitialCondition("Across the building the non-zero hours of operation range from #{hoo_summary_hash[:final_hoo_dur_range].min} hours to #{hoo_summary_hash[:final_hoo_dur_range].max} hours. Start of hours of operation range from #{hoo_summary_hash[:final_hoo_start_range].min} to #{hoo_summary_hash[:final_hoo_start_range].max}. One or more hours of operation schedules used contain a profile with 0 hours of operation.") else runner.registerInitialCondition("Across the building the hours of operation range from #{hoo_summary_hash[:final_hoo_dur_range].min} hours to #{hoo_summary_hash[:final_hoo_dur_range].max} hours. Start of hours of operation range from #{hoo_summary_hash[:final_hoo_start_range].min} to #{hoo_summary_hash[:final_hoo_start_range].max}.") end # gather hours of operation schedules used by this model used_hoo_sch_sets = {} model.getSpaces.sort.each do |space| default_sch_type = OpenStudio::Model::DefaultScheduleType.new('HoursofOperationSchedule') hours_of_operation = space.getDefaultSchedule(default_sch_type) if !hours_of_operation.is_initialized runner.registerWarning("Hours of Operation Schedule is not set for #{space.name}.") next end hours_of_operation_hash = OpenstudioStandards::Space.space_hours_of_operation(space) used_hoo_sch_sets[hours_of_operation.get] = hours_of_operation_hash end # loop through and alter hours of operation schedules runner.registerInfo("There are #{used_hoo_sch_sets.uniq.size} hours of operation schedules in the model to alter.") # process weekday profiles runner.registerInfo('Altering hours of operation schedules for weekday profiles') weekday = process_hoo(used_hoo_sch_sets, model, runner, args, ['mon', 'tue', 'wed', 'thur', 'fri'], args['hoo_start_weekday'], args['hoo_dur_weekday']) # process saturday profiles runner.registerInfo('Altering hours of operation schedules for saturday profiles') saturday = process_hoo(used_hoo_sch_sets, model, runner, args, ['sat'], args['hoo_start_saturday'], args['hoo_dur_saturday']) # process sunday profiles runner.registerInfo('Altering hours of operation schedules for sunday profiles') sunday = process_hoo(used_hoo_sch_sets, model, runner, args, ['sun'], args['hoo_start_sunday'], args['hoo_dur_sunday']) # TODO: - need to address this error when manipulating schedules # [openstudio.standards.ScheduleRuleset] <1> Pre-interpolated processed hash for Large Office Bldg Equip Default Schedule has one or more out of order conflicts: [[3.5, 0.8], [4.5, 0.6], [5.0, 0.6], [7.0, 0.5], [9.0, 0.4], [6.0, 0.4], [10.0, 0.9], [16.5, 0.9], [17.5, 0.8], [18.5, 0.9], [21.5, 0.9]]. Method will stop because Error on Out of Order was set to true. # model_build_parametric_schedules parametric_schedules = OpenstudioStandards::Schedules.model_apply_parametric_schedules(model, ramp_frequency: nil, infer_hoo_for_non_assigned_objects: true, error_on_out_of_order: false) runner.registerInfo("Created #{parametric_schedules.size} parametric schedules.") # report final condition of model hoo_summary_hash = hoo_summary(model, runner, standard) if !hoo_summary_hash[:zero_hoo].empty? runner.registerFinalCondition("Across the building the non-zero hours of operation range from #{hoo_summary_hash[:final_hoo_dur_range].min} hours to #{hoo_summary_hash[:final_hoo_dur_range].max} hours. Start of hours of operation range from #{hoo_summary_hash[:final_hoo_start_range].min} to #{hoo_summary_hash[:final_hoo_start_range].max}. One or more hours of operation schedules used contain a profile with 0 hours of operation.") else runner.registerFinalCondition("Across the building the hours of operation range from #{hoo_summary_hash[:final_hoo_dur_range].min} hours to #{hoo_summary_hash[:final_hoo_dur_range].max} hours. Start of hours of operation range from #{hoo_summary_hash[:final_hoo_start_range].min} to #{hoo_summary_hash[:final_hoo_start_range].max}.") end # gather log (runner, debug) reset_log # TODO: - adding hours of operation to a schedule that doesn't have them to start with, like a sunday, can be problematic # todo - start of day may not be reliable and there may not be formula inputs to show what occupied behavior is # todo - in a situation like that it could be good to get formula from day that was non-zero to start with like weekday or saturday. # todo - maybe standards can do something like this when making the formulas in the first place. return true end |