openstudio-load-flexibility-measures 0.9.0 → 0.10.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +6 -0
  3. data/Gemfile +5 -5
  4. data/LICENSE.md +1 -1
  5. data/README.md +1 -0
  6. data/lib/measures/PeakPeriodSchedulesShift/LICENSE.md +13 -0
  7. data/lib/measures/PeakPeriodSchedulesShift/README.md +140 -0
  8. data/lib/measures/PeakPeriodSchedulesShift/README.md.erb +106 -0
  9. data/lib/measures/PeakPeriodSchedulesShift/docs/measures-overview.png +0 -0
  10. data/lib/measures/PeakPeriodSchedulesShift/docs/other-examples1.png +0 -0
  11. data/lib/measures/PeakPeriodSchedulesShift/docs/other-examples2.png +0 -0
  12. data/lib/measures/PeakPeriodSchedulesShift/docs/other-examples3.png +0 -0
  13. data/lib/measures/PeakPeriodSchedulesShift/measure.rb +441 -0
  14. data/lib/measures/PeakPeriodSchedulesShift/measure.xml +230 -0
  15. data/lib/measures/PeakPeriodSchedulesShift/tests/PeakPeriodSchedulesShift_Test.rb +603 -0
  16. data/lib/measures/PeakPeriodSchedulesShift/tests/base-schedules-detailed-occupancy-stochastic.osm +8306 -0
  17. data/lib/measures/PeakPeriodSchedulesShift/tests/base.osm +15647 -0
  18. data/lib/measures/PeakPeriodSchedulesShift/tests/files/schedules20230418-20180-18nykxu.csv +8761 -0
  19. data/lib/measures/PeakPeriodSchedulesShift/tests/files/unmodified_schedules.csv +8761 -0
  20. data/lib/measures/PeakPeriodSchedulesShift/tests/test_smooth_schedules.osm +23698 -0
  21. data/lib/measures/PeakPeriodSchedulesShift/tests/test_stochastic_schedules.osm +8985 -0
  22. data/lib/measures/PeakPeriodSchedulesShift/tests/test_stochastic_schedules_no_stacking.osm +8306 -0
  23. data/lib/measures/ShiftScheduleByType/LICENSE.md +1 -1
  24. data/lib/measures/ShiftScheduleByType/measure.xml +23 -23
  25. data/lib/measures/add_central_ice_storage/LICENSE.md +1 -1
  26. data/lib/measures/add_central_ice_storage/measure.xml +3 -3
  27. data/lib/measures/add_hpwh/LICENSE.md +1 -1
  28. data/lib/measures/add_hpwh/measure.rb +19 -19
  29. data/lib/measures/add_hpwh/measure.xml +4 -4
  30. data/lib/measures/add_packaged_ice_storage/LICENSE.md +1 -1
  31. data/lib/measures/add_packaged_ice_storage/measure.xml +3 -3
  32. data/lib/openstudio/load_flexibility_measures/version.rb +1 -1
  33. data/openstudio-load-flexibility-measures.gemspec +2 -4
  34. metadata +23 -34
@@ -0,0 +1,603 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
3
+ # See also https://openstudio.net/license
4
+ # *******************************************************************************
5
+
6
+ # frozen_string_literal: true
7
+
8
+ require 'openstudio'
9
+ require 'openstudio/measure/ShowRunnerOutput'
10
+ require 'minitest/autorun'
11
+ require_relative '../measure.rb'
12
+ require 'fileutils'
13
+
14
+ class PeakPeriodSchedulesShiftTest < Minitest::Test
15
+ def setup
16
+ # need to avoid using the modified schedules as the starting point for subsequent tests
17
+ src = File.expand_path(File.join(File.dirname(__FILE__), 'files/unmodified_schedules.csv'))
18
+ des = File.expand_path(File.join(File.dirname(__FILE__), 'files/schedules20230418-20180-18nykxu.csv'))
19
+ FileUtils.cp(src, des)
20
+ end
21
+
22
+ def test_error_begin_hour_after_end_hour
23
+ # create an instance of the measure
24
+ measure = PeakPeriodSchedulesShift.new
25
+
26
+ # create an instance of a runner
27
+ workflow_json = OpenStudio::WorkflowJSON.new
28
+ workflow_json.addFilePath(File.join(File.dirname(__FILE__), 'files'))
29
+ runner = OpenStudio::Measure::OSRunner.new(workflow_json)
30
+
31
+ # load the test model
32
+ translator = OpenStudio::OSVersion::VersionTranslator.new
33
+ path = OpenStudio::Path.new(File.dirname(__FILE__) + '/base.osm')
34
+ model = translator.loadModel(path)
35
+ assert(!model.empty?)
36
+ model = model.get
37
+ model.setWorkflowJSON(workflow_json)
38
+
39
+ # get arguments and test that they are what we are expecting
40
+ arguments = measure.arguments(model)
41
+ assert_equal(6, arguments.size)
42
+
43
+ count = -1
44
+
45
+ assert_equal('schedules_peak_period', arguments[count += 1].name)
46
+ assert_equal('schedules_peak_period_delay', arguments[count += 1].name)
47
+ assert_equal('schedules_peak_period_allow_stacking', arguments[count += 1].name)
48
+ assert_equal('schedules_peak_period_weekdays_only', arguments[count += 1].name)
49
+ assert_equal('schedules_peak_period_schedule_rulesets_names', arguments[count += 1].name)
50
+ assert_equal('schedules_peak_period_schedule_files_column_names', arguments[count + 1].name)
51
+
52
+ # set argument values to good values and run the measure on model with spaces
53
+ arguments = measure.arguments(model)
54
+ argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
55
+
56
+ count = -1
57
+
58
+ schedules_peak_period = arguments[count += 1].clone
59
+ assert(schedules_peak_period.setValue('19 - 17'))
60
+ argument_map['schedules_peak_period'] = schedules_peak_period
61
+
62
+ schedules_peak_period_delay = arguments[count += 1].clone
63
+ assert(schedules_peak_period_delay.setValue(1))
64
+ argument_map['schedules_peak_period_delay'] = schedules_peak_period_delay
65
+
66
+ schedules_peak_period_allow_stacking = arguments[count += 1].clone
67
+ # assert(schedules_peak_period_allow_stacking.setValue(true))
68
+ argument_map['schedules_peak_period_allow_stacking'] = schedules_peak_period_allow_stacking
69
+
70
+ schedules_peak_period_weekdays_only = arguments[count += 1].clone
71
+ # assert(schedules_peak_period_weekdays_only.setValue(true))
72
+ argument_map['schedules_peak_period_weekdays_only'] = schedules_peak_period_weekdays_only
73
+
74
+ schedules_peak_period_schedule_rulesets_names = arguments[count += 1].clone
75
+ assert(schedules_peak_period_schedule_rulesets_names.setValue('fridge, dishwasher, clothes washer, clothes dryer, cooking range, misc tv schedule, misc plug loads schedule, lighting schedule, exterior lighting schedule'))
76
+ argument_map['schedules_peak_period_schedule_rulesets_names'] = schedules_peak_period_schedule_rulesets_names
77
+
78
+ schedules_peak_period_schedule_files_column_names = arguments[count + 1].clone
79
+ # assert(schedules_peak_period_schedule_files_column_names.setValue(''))
80
+ argument_map['schedules_peak_period_schedule_files_column_names'] = schedules_peak_period_schedule_files_column_names
81
+
82
+ measure.run(model, runner, argument_map)
83
+ result = runner.result
84
+ show_output(result)
85
+ assert(result.value.valueName == 'Fail')
86
+ assert(result.warnings.empty?)
87
+ assert_equal(result.errors.size, 1)
88
+ end
89
+
90
+ def test_error_peak_period_plus_delay_greater_than_12
91
+ # create an instance of the measure
92
+ measure = PeakPeriodSchedulesShift.new
93
+
94
+ # create an instance of a runner
95
+ workflow_json = OpenStudio::WorkflowJSON.new
96
+ workflow_json.addFilePath(File.join(File.dirname(__FILE__), 'files'))
97
+ runner = OpenStudio::Measure::OSRunner.new(workflow_json)
98
+
99
+ # load the test model
100
+ translator = OpenStudio::OSVersion::VersionTranslator.new
101
+ path = OpenStudio::Path.new(File.dirname(__FILE__) + '/base.osm')
102
+ model = translator.loadModel(path)
103
+ assert(!model.empty?)
104
+ model = model.get
105
+ model.setWorkflowJSON(workflow_json)
106
+
107
+ # get arguments and test that they are what we are expecting
108
+ arguments = measure.arguments(model)
109
+ assert_equal(6, arguments.size)
110
+
111
+ count = -1
112
+
113
+ assert_equal('schedules_peak_period', arguments[count += 1].name)
114
+ assert_equal('schedules_peak_period_delay', arguments[count += 1].name)
115
+ assert_equal('schedules_peak_period_allow_stacking', arguments[count += 1].name)
116
+ assert_equal('schedules_peak_period_weekdays_only', arguments[count += 1].name)
117
+ assert_equal('schedules_peak_period_schedule_rulesets_names', arguments[count += 1].name)
118
+ assert_equal('schedules_peak_period_schedule_files_column_names', arguments[count + 1].name)
119
+
120
+ # set argument values to good values and run the measure on model with spaces
121
+ arguments = measure.arguments(model)
122
+ argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
123
+
124
+ count = -1
125
+
126
+ schedules_peak_period = arguments[count += 1].clone
127
+ assert(schedules_peak_period.setValue('1 - 9'))
128
+ argument_map['schedules_peak_period'] = schedules_peak_period
129
+
130
+ schedules_peak_period_delay = arguments[count += 1].clone
131
+ assert(schedules_peak_period_delay.setValue(5))
132
+ argument_map['schedules_peak_period_delay'] = schedules_peak_period_delay
133
+
134
+ schedules_peak_period_allow_stacking = arguments[count += 1].clone
135
+ # assert(schedules_peak_period_allow_stacking.setValue(true))
136
+ argument_map['schedules_peak_period_allow_stacking'] = schedules_peak_period_allow_stacking
137
+
138
+ schedules_peak_period_weekdays_only = arguments[count += 1].clone
139
+ # assert(schedules_peak_period_weekdays_only.setValue(true))
140
+ argument_map['schedules_peak_period_weekdays_only'] = schedules_peak_period_weekdays_only
141
+
142
+ schedules_peak_period_schedule_rulesets_names = arguments[count += 1].clone
143
+ assert(schedules_peak_period_schedule_rulesets_names.setValue('fridge, dishwasher, clothes washer, clothes dryer, cooking range, misc tv schedule, misc plug loads schedule, lighting schedule, exterior lighting schedule'))
144
+ argument_map['schedules_peak_period_schedule_rulesets_names'] = schedules_peak_period_schedule_rulesets_names
145
+
146
+ schedules_peak_period_schedule_files_column_names = arguments[count + 1].clone
147
+ # assert(schedules_peak_period_schedule_files_column_names.setValue(''))
148
+ argument_map['schedules_peak_period_schedule_files_column_names'] = schedules_peak_period_schedule_files_column_names
149
+
150
+ measure.run(model, runner, argument_map)
151
+ result = runner.result
152
+ show_output(result)
153
+ assert(result.value.valueName == 'Fail')
154
+ assert(result.warnings.empty?)
155
+ assert_equal(result.errors.size, 1)
156
+ end
157
+
158
+ def test_error_peak_period_shift_into_next_day
159
+ # create an instance of the measure
160
+ measure = PeakPeriodSchedulesShift.new
161
+
162
+ # create an instance of a runner
163
+ workflow_json = OpenStudio::WorkflowJSON.new
164
+ workflow_json.addFilePath(File.join(File.dirname(__FILE__), 'files'))
165
+ runner = OpenStudio::Measure::OSRunner.new(workflow_json)
166
+
167
+ # load the test model
168
+ translator = OpenStudio::OSVersion::VersionTranslator.new
169
+ path = OpenStudio::Path.new(File.dirname(__FILE__) + '/base.osm')
170
+ model = translator.loadModel(path)
171
+ assert(!model.empty?)
172
+ model = model.get
173
+ model.setWorkflowJSON(workflow_json)
174
+
175
+ # get arguments and test that they are what we are expecting
176
+ arguments = measure.arguments(model)
177
+ assert_equal(6, arguments.size)
178
+
179
+ count = -1
180
+
181
+ assert_equal('schedules_peak_period', arguments[count += 1].name)
182
+ assert_equal('schedules_peak_period_delay', arguments[count += 1].name)
183
+ assert_equal('schedules_peak_period_allow_stacking', arguments[count += 1].name)
184
+ assert_equal('schedules_peak_period_weekdays_only', arguments[count += 1].name)
185
+ assert_equal('schedules_peak_period_schedule_rulesets_names', arguments[count += 1].name)
186
+ assert_equal('schedules_peak_period_schedule_files_column_names', arguments[count + 1].name)
187
+
188
+ # set argument values to good values and run the measure on model with spaces
189
+ arguments = measure.arguments(model)
190
+ argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
191
+
192
+ count = -1
193
+
194
+ schedules_peak_period = arguments[count += 1].clone
195
+ assert(schedules_peak_period.setValue('17 - 19'))
196
+ argument_map['schedules_peak_period'] = schedules_peak_period
197
+
198
+ schedules_peak_period_delay = arguments[count += 1].clone
199
+ assert(schedules_peak_period_delay.setValue(4))
200
+ argument_map['schedules_peak_period_delay'] = schedules_peak_period_delay
201
+
202
+ schedules_peak_period_allow_stacking = arguments[count += 1].clone
203
+ # assert(schedules_peak_period_allow_stacking.setValue(true))
204
+ argument_map['schedules_peak_period_allow_stacking'] = schedules_peak_period_allow_stacking
205
+
206
+ schedules_peak_period_weekdays_only = arguments[count += 1].clone
207
+ # assert(schedules_peak_period_weekdays_only.setValue(true))
208
+ argument_map['schedules_peak_period_weekdays_only'] = schedules_peak_period_weekdays_only
209
+
210
+ schedules_peak_period_schedule_rulesets_names = arguments[count += 1].clone
211
+ assert(schedules_peak_period_schedule_rulesets_names.setValue('fridge, dishwasher, clothes washer, clothes dryer, cooking range, misc tv schedule, misc plug loads schedule, lighting schedule, exterior lighting schedule'))
212
+ argument_map['schedules_peak_period_schedule_rulesets_names'] = schedules_peak_period_schedule_rulesets_names
213
+
214
+ schedules_peak_period_schedule_files_column_names = arguments[count + 1].clone
215
+ # assert(schedules_peak_period_schedule_files_column_names.setValue(''))
216
+ argument_map['schedules_peak_period_schedule_files_column_names'] = schedules_peak_period_schedule_files_column_names
217
+
218
+ measure.run(model, runner, argument_map)
219
+ result = runner.result
220
+ show_output(result)
221
+ assert(result.value.valueName == 'Fail')
222
+ assert(result.warnings.empty?)
223
+ assert_equal(result.errors.size, 1)
224
+ end
225
+
226
+ def test_smooth_schedules
227
+ # create an instance of the measure
228
+ measure = PeakPeriodSchedulesShift.new
229
+
230
+ # create an instance of a runner
231
+ workflow_json = OpenStudio::WorkflowJSON.new
232
+ workflow_json.addFilePath(File.join(File.dirname(__FILE__), 'files'))
233
+ runner = OpenStudio::Measure::OSRunner.new(workflow_json)
234
+
235
+ # load the test model
236
+ translator = OpenStudio::OSVersion::VersionTranslator.new
237
+ path = OpenStudio::Path.new(File.dirname(__FILE__) + '/base.osm')
238
+ model = translator.loadModel(path)
239
+ assert(!model.empty?)
240
+ model = model.get
241
+ model.setWorkflowJSON(workflow_json)
242
+
243
+ # get arguments and test that they are what we are expecting
244
+ arguments = measure.arguments(model)
245
+ assert_equal(6, arguments.size)
246
+
247
+ count = -1
248
+
249
+ assert_equal('schedules_peak_period', arguments[count += 1].name)
250
+ assert_equal('schedules_peak_period_delay', arguments[count += 1].name)
251
+ assert_equal('schedules_peak_period_allow_stacking', arguments[count += 1].name)
252
+ assert_equal('schedules_peak_period_weekdays_only', arguments[count += 1].name)
253
+ assert_equal('schedules_peak_period_schedule_rulesets_names', arguments[count += 1].name)
254
+ assert_equal('schedules_peak_period_schedule_files_column_names', arguments[count + 1].name)
255
+
256
+ # set argument values to good values and run the measure on model with spaces
257
+ arguments = measure.arguments(model)
258
+ argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
259
+
260
+ count = -1
261
+
262
+ schedules_peak_period = arguments[count += 1].clone
263
+ assert(schedules_peak_period.setValue('17 - 19'))
264
+ argument_map['schedules_peak_period'] = schedules_peak_period
265
+
266
+ schedules_peak_period_delay = arguments[count += 1].clone
267
+ assert(schedules_peak_period_delay.setValue(1))
268
+ argument_map['schedules_peak_period_delay'] = schedules_peak_period_delay
269
+
270
+ schedules_peak_period_allow_stacking = arguments[count += 1].clone
271
+ # assert(schedules_peak_period_allow_stacking.setValue(true))
272
+ argument_map['schedules_peak_period_allow_stacking'] = schedules_peak_period_allow_stacking
273
+
274
+ schedules_peak_period_weekdays_only = arguments[count += 1].clone
275
+ # assert(schedules_peak_period_weekdays_only.setValue(true))
276
+ argument_map['schedules_peak_period_weekdays_only'] = schedules_peak_period_weekdays_only
277
+
278
+ schedules_peak_period_schedule_rulesets_names = arguments[count += 1].clone
279
+ assert(schedules_peak_period_schedule_rulesets_names.setValue('fridge, dishwasher, clothes washer, clothes dryer, cooking range, misc tv schedule, misc plug loads schedule, lighting schedule, exterior lighting schedule'))
280
+ argument_map['schedules_peak_period_schedule_rulesets_names'] = schedules_peak_period_schedule_rulesets_names
281
+
282
+ schedules_peak_period_schedule_files_column_names = arguments[count + 1].clone
283
+ # assert(schedules_peak_period_schedule_files_column_names.setValue(''))
284
+ argument_map['schedules_peak_period_schedule_files_column_names'] = schedules_peak_period_schedule_files_column_names
285
+
286
+ # before
287
+ schedule_rulesets = {}
288
+ model.getScheduleRulesets.each do |schedule_ruleset|
289
+ schedule_rulesets[schedule_ruleset.name.to_s] = schedule_ruleset
290
+ end
291
+ assert(!schedule_rulesets.empty?)
292
+ assert_equal(schedule_rulesets['fridge'].scheduleRules.size, 7)
293
+ shiftable_rule = schedule_rulesets['fridge'].scheduleRules.find { |schedule_rule| schedule_rule.name.to_s == 'fridge allday ruleset1' }
294
+ values_before = measure.get_hourly_values(shiftable_rule.daySchedule)
295
+
296
+ schedule_files_before = {}
297
+ model.getExternalFiles.each do |external_file|
298
+ external_file_path = external_file.filePath.to_s
299
+
300
+ schedules = Schedules.new(file_path: external_file_path)
301
+ schedule_files_before = schedules.schedules
302
+ end
303
+
304
+ measure.run(model, runner, argument_map)
305
+ result = runner.result
306
+ show_output(result)
307
+ assert(result.value.valueName == 'Success')
308
+ assert(result.warnings.empty?)
309
+ assert_equal(result.info.size, 9)
310
+
311
+ # save the model
312
+ output_file_path = OpenStudio::Path.new(File.dirname(__FILE__) + '/test_smooth_schedules.osm')
313
+ model.save(output_file_path, true)
314
+
315
+ # after
316
+ model.getScheduleRulesets.each do |schedule_ruleset|
317
+ schedule_rulesets[schedule_ruleset.name.to_s] = schedule_ruleset
318
+ end
319
+ assert(!schedule_rulesets.empty?)
320
+ assert_equal(schedule_rulesets['fridge'].scheduleRules.size, 14)
321
+ shifted_rule = schedule_rulesets['fridge'].scheduleRules.find { |schedule_rule| schedule_rule.name.to_s == 'fridge allday ruleset1 Shifted' }
322
+ assert(shifted_rule.applyWeekdays)
323
+ assert(!shifted_rule.applyWeekends)
324
+ values_after = measure.get_hourly_values(shifted_rule.daySchedule)
325
+ assert(values_before != values_after)
326
+ assert_in_epsilon(values_before.sum, values_after.sum, 0.00001)
327
+
328
+ schedule_files_after = {}
329
+ model.getExternalFiles.each do |external_file|
330
+ external_file_path = external_file.filePath.to_s
331
+
332
+ schedules = Schedules.new(file_path: external_file_path)
333
+ schedule_files_after = schedules.schedules
334
+ end
335
+
336
+ # check schedule files
337
+ assert(schedule_files_before.empty?)
338
+ assert(schedule_files_after.empty?)
339
+ end
340
+
341
+ def test_stochastic_schedules
342
+ # create an instance of the measure
343
+ measure = PeakPeriodSchedulesShift.new
344
+
345
+ # create an instance of a runner
346
+ workflow_json = OpenStudio::WorkflowJSON.new
347
+ workflow_json.addFilePath(File.join(File.dirname(__FILE__), 'files'))
348
+ runner = OpenStudio::Measure::OSRunner.new(workflow_json)
349
+
350
+ # load the test model
351
+ translator = OpenStudio::OSVersion::VersionTranslator.new
352
+ path = OpenStudio::Path.new(File.dirname(__FILE__) + '/base-schedules-detailed-occupancy-stochastic.osm')
353
+ model = translator.loadModel(path)
354
+ assert(!model.empty?)
355
+ model = model.get
356
+ model.setWorkflowJSON(workflow_json)
357
+
358
+ # get arguments and test that they are what we are expecting
359
+ arguments = measure.arguments(model)
360
+ assert_equal(6, arguments.size)
361
+
362
+ count = -1
363
+
364
+ assert_equal('schedules_peak_period', arguments[count += 1].name)
365
+ assert_equal('schedules_peak_period_delay', arguments[count += 1].name)
366
+ assert_equal('schedules_peak_period_allow_stacking', arguments[count += 1].name)
367
+ assert_equal('schedules_peak_period_weekdays_only', arguments[count += 1].name)
368
+ assert_equal('schedules_peak_period_schedule_rulesets_names', arguments[count += 1].name)
369
+ assert_equal('schedules_peak_period_schedule_files_column_names', arguments[count + 1].name)
370
+
371
+ # set argument values to good values and run the measure on model with spaces
372
+ arguments = measure.arguments(model)
373
+ argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
374
+
375
+ count = -1
376
+
377
+ schedules_peak_period = arguments[count += 1].clone
378
+ assert(schedules_peak_period.setValue('17 - 19'))
379
+ argument_map['schedules_peak_period'] = schedules_peak_period
380
+
381
+ schedules_peak_period_delay = arguments[count += 1].clone
382
+ assert(schedules_peak_period_delay.setValue(1))
383
+ argument_map['schedules_peak_period_delay'] = schedules_peak_period_delay
384
+
385
+ schedules_peak_period_allow_stacking = arguments[count += 1].clone
386
+ assert(schedules_peak_period_allow_stacking.setValue(true))
387
+ argument_map['schedules_peak_period_allow_stacking'] = schedules_peak_period_allow_stacking
388
+
389
+ schedules_peak_period_weekdays_only = arguments[count += 1].clone
390
+ # assert(schedules_peak_period_weekdays_only.setValue(true))
391
+ argument_map['schedules_peak_period_weekdays_only'] = schedules_peak_period_weekdays_only
392
+
393
+ schedules_peak_period_schedule_rulesets_names = arguments[count += 1].clone
394
+ assert(schedules_peak_period_schedule_rulesets_names.setValue('fridge'))
395
+ argument_map['schedules_peak_period_schedule_rulesets_names'] = schedules_peak_period_schedule_rulesets_names
396
+
397
+ schedules_peak_period_schedule_files_column_names = arguments[count + 1].clone
398
+ assert(schedules_peak_period_schedule_files_column_names.setValue('dishwasher, clothes_washer, clothes_dryer, cooking_range'))
399
+ argument_map['schedules_peak_period_schedule_files_column_names'] = schedules_peak_period_schedule_files_column_names
400
+
401
+ # before
402
+ schedule_rulesets = {}
403
+ model.getScheduleRulesets.each do |schedule_ruleset|
404
+ schedule_rulesets[schedule_ruleset.name.to_s] = schedule_ruleset
405
+ end
406
+ assert(!schedule_rulesets.empty?)
407
+ assert_equal(schedule_rulesets['fridge'].scheduleRules.size, 7)
408
+ shiftable_rule = schedule_rulesets['fridge'].scheduleRules.find { |schedule_rule| schedule_rule.name.to_s == 'fridge allday ruleset1' }
409
+ values_before = measure.get_hourly_values(shiftable_rule.daySchedule)
410
+
411
+ schedule_files_before = {}
412
+ model.getExternalFiles.each do |external_file|
413
+ external_file_path = external_file.filePath.to_s
414
+
415
+ schedules = Schedules.new(file_path: external_file_path)
416
+ schedule_files_before = schedules.schedules
417
+ end
418
+
419
+ measure.run(model, runner, argument_map)
420
+ result = runner.result
421
+ show_output(result)
422
+ assert(result.value.valueName == 'Success')
423
+ assert(result.warnings.empty?)
424
+ assert_equal(result.info.size, 5)
425
+
426
+ # save the model
427
+ output_file_path = OpenStudio::Path.new(File.dirname(__FILE__) + '/test_stochastic_schedules.osm')
428
+ model.save(output_file_path, true)
429
+
430
+ # after
431
+ model.getScheduleRulesets.each do |schedule_ruleset|
432
+ schedule_rulesets[schedule_ruleset.name.to_s] = schedule_ruleset
433
+ end
434
+ assert(!schedule_rulesets.empty?)
435
+ assert_equal(schedule_rulesets['fridge'].scheduleRules.size, 14)
436
+ shifted_rule = schedule_rulesets['fridge'].scheduleRules.find { |schedule_rule| schedule_rule.name.to_s == 'fridge allday ruleset1 Shifted' }
437
+ assert(shifted_rule.applyWeekdays)
438
+ assert(!shifted_rule.applyWeekends)
439
+ values_after = measure.get_hourly_values(shifted_rule.daySchedule)
440
+ assert(values_before != values_after)
441
+ assert_in_epsilon(values_before.sum, values_after.sum, 0.00001)
442
+
443
+ schedule_files_after = {}
444
+ model.getExternalFiles.each do |external_file|
445
+ external_file_path = external_file.filePath.to_s
446
+
447
+ schedules = Schedules.new(file_path: external_file_path)
448
+ schedule_files_after = schedules.schedules
449
+ end
450
+
451
+ # check schedule files
452
+ assert(!schedule_files_before.empty?)
453
+ assert(!schedule_files_after.empty?)
454
+
455
+ assert(schedule_files_before['ceiling_fan'] == schedule_files_after['ceiling_fan'])
456
+ assert(schedule_files_before['hot_water_clothes_washer'] == schedule_files_after['hot_water_clothes_washer'])
457
+ assert(schedule_files_before['hot_water_dishwasher'] == schedule_files_after['hot_water_dishwasher'])
458
+ assert(schedule_files_before['hot_water_fixtures'] == schedule_files_after['hot_water_fixtures'])
459
+ assert(schedule_files_before['lighting_garage'] == schedule_files_after['lighting_garage'])
460
+ assert(schedule_files_before['lighting_interior'] == schedule_files_after['lighting_interior'])
461
+ assert(schedule_files_before['occupants'] == schedule_files_after['occupants'])
462
+ assert(schedule_files_before['plug_loads_other'] == schedule_files_after['plug_loads_other'])
463
+ assert(schedule_files_before['plug_loads_tv'] == schedule_files_after['plug_loads_tv'])
464
+
465
+ assert(schedule_files_before['clothes_dryer'] != schedule_files_after['clothes_dryer'])
466
+ assert(schedule_files_before['clothes_washer'] != schedule_files_after['clothes_washer'])
467
+ assert(schedule_files_before['cooking_range'] != schedule_files_after['cooking_range'])
468
+ assert(schedule_files_before['dishwasher'] != schedule_files_after['dishwasher'])
469
+
470
+ assert_equal(schedule_files_before['clothes_dryer'].sum, schedule_files_after['clothes_dryer'].sum)
471
+ assert_equal(schedule_files_before['clothes_washer'].sum, schedule_files_after['clothes_washer'].sum)
472
+ assert_equal(schedule_files_before['cooking_range'].sum, schedule_files_after['cooking_range'].sum)
473
+ assert_equal(schedule_files_before['dishwasher'].sum, schedule_files_after['dishwasher'].sum)
474
+ end
475
+
476
+ def test_stochastic_schedules_no_stacking
477
+ # create an instance of the measure
478
+ measure = PeakPeriodSchedulesShift.new
479
+
480
+ # create an instance of a runner
481
+ workflow_json = OpenStudio::WorkflowJSON.new
482
+ workflow_json.addFilePath(File.join(File.dirname(__FILE__), 'files'))
483
+ runner = OpenStudio::Measure::OSRunner.new(workflow_json)
484
+
485
+ # load the test model
486
+ translator = OpenStudio::OSVersion::VersionTranslator.new
487
+ path = OpenStudio::Path.new(File.dirname(__FILE__) + '/base-schedules-detailed-occupancy-stochastic.osm')
488
+ model = translator.loadModel(path)
489
+ assert(!model.empty?)
490
+ model = model.get
491
+ model.setWorkflowJSON(workflow_json)
492
+
493
+ # get arguments and test that they are what we are expecting
494
+ arguments = measure.arguments(model)
495
+ assert_equal(6, arguments.size)
496
+
497
+ count = -1
498
+
499
+ assert_equal('schedules_peak_period', arguments[count += 1].name)
500
+ assert_equal('schedules_peak_period_delay', arguments[count += 1].name)
501
+ assert_equal('schedules_peak_period_allow_stacking', arguments[count += 1].name)
502
+ assert_equal('schedules_peak_period_weekdays_only', arguments[count += 1].name)
503
+ assert_equal('schedules_peak_period_schedule_rulesets_names', arguments[count += 1].name)
504
+ assert_equal('schedules_peak_period_schedule_files_column_names', arguments[count + 1].name)
505
+
506
+ # set argument values to good values and run the measure on model with spaces
507
+ arguments = measure.arguments(model)
508
+ argument_map = OpenStudio::Measure.convertOSArgumentVectorToMap(arguments)
509
+
510
+ count = -1
511
+
512
+ schedules_peak_period = arguments[count += 1].clone
513
+ assert(schedules_peak_period.setValue('17 - 19'))
514
+ argument_map['schedules_peak_period'] = schedules_peak_period
515
+
516
+ schedules_peak_period_delay = arguments[count += 1].clone
517
+ assert(schedules_peak_period_delay.setValue(1))
518
+ argument_map['schedules_peak_period_delay'] = schedules_peak_period_delay
519
+
520
+ schedules_peak_period_allow_stacking = arguments[count += 1].clone
521
+ assert(schedules_peak_period_allow_stacking.setValue(false))
522
+ argument_map['schedules_peak_period_allow_stacking'] = schedules_peak_period_allow_stacking
523
+
524
+ schedules_peak_period_weekdays_only = arguments[count += 1].clone
525
+ # assert(schedules_peak_period_weekdays_only.setValue(false))
526
+ argument_map['schedules_peak_period_weekdays_only'] = schedules_peak_period_weekdays_only
527
+
528
+ schedules_peak_period_schedule_rulesets_names = arguments[count += 1].clone
529
+ assert(schedules_peak_period_schedule_rulesets_names.setValue('fridge'))
530
+ argument_map['schedules_peak_period_schedule_rulesets_names'] = schedules_peak_period_schedule_rulesets_names
531
+
532
+ schedules_peak_period_schedule_files_column_names = arguments[count + 1].clone
533
+ assert(schedules_peak_period_schedule_files_column_names.setValue('dishwasher, clothes_washer, clothes_dryer, cooking_range'))
534
+ argument_map['schedules_peak_period_schedule_files_column_names'] = schedules_peak_period_schedule_files_column_names
535
+
536
+ # before
537
+ schedule_rulesets = {}
538
+ model.getScheduleRulesets.each do |schedule_ruleset|
539
+ schedule_rulesets[schedule_ruleset.name.to_s] = schedule_ruleset
540
+ end
541
+ assert(!schedule_rulesets.empty?)
542
+ assert_equal(schedule_rulesets['fridge'].scheduleRules.size, 7)
543
+
544
+ schedule_files_before = {}
545
+ model.getExternalFiles.each do |external_file|
546
+ external_file_path = external_file.filePath.to_s
547
+
548
+ schedules = Schedules.new(file_path: external_file_path)
549
+ schedule_files_before = schedules.schedules
550
+ end
551
+
552
+ measure.run(model, runner, argument_map)
553
+ result = runner.result
554
+ show_output(result)
555
+ assert(result.value.valueName == 'Success')
556
+ assert(result.warnings.empty?)
557
+ assert_equal(result.info.size, 5)
558
+
559
+ # save the model
560
+ output_file_path = OpenStudio::Path.new(File.dirname(__FILE__) + '/test_stochastic_schedules_no_stacking.osm')
561
+ model.save(output_file_path, true)
562
+
563
+ # after
564
+ model.getScheduleRulesets.each do |schedule_ruleset|
565
+ schedule_rulesets[schedule_ruleset.name.to_s] = schedule_ruleset
566
+ end
567
+ assert(!schedule_rulesets.empty?)
568
+ assert_equal(schedule_rulesets['fridge'].scheduleRules.size, 7)
569
+ shifted_rule = schedule_rulesets['fridge'].scheduleRules.find { |schedule_rule| schedule_rule.name.to_s == 'fridge allday ruleset1 Shifted' }
570
+ assert(shifted_rule.nil?)
571
+ schedule_files_after = {}
572
+ model.getExternalFiles.each do |external_file|
573
+ external_file_path = external_file.filePath.to_s
574
+
575
+ schedules = Schedules.new(file_path: external_file_path)
576
+ schedule_files_after = schedules.schedules
577
+ end
578
+
579
+ # check schedule files
580
+ assert(!schedule_files_before.empty?)
581
+ assert(!schedule_files_after.empty?)
582
+
583
+ assert(schedule_files_before['ceiling_fan'] == schedule_files_after['ceiling_fan'])
584
+ assert(schedule_files_before['hot_water_clothes_washer'] == schedule_files_after['hot_water_clothes_washer'])
585
+ assert(schedule_files_before['hot_water_dishwasher'] == schedule_files_after['hot_water_dishwasher'])
586
+ assert(schedule_files_before['hot_water_fixtures'] == schedule_files_after['hot_water_fixtures'])
587
+ assert(schedule_files_before['lighting_garage'] == schedule_files_after['lighting_garage'])
588
+ assert(schedule_files_before['lighting_interior'] == schedule_files_after['lighting_interior'])
589
+ assert(schedule_files_before['occupants'] == schedule_files_after['occupants'])
590
+ assert(schedule_files_before['plug_loads_other'] == schedule_files_after['plug_loads_other'])
591
+ assert(schedule_files_before['plug_loads_tv'] == schedule_files_after['plug_loads_tv'])
592
+
593
+ assert(schedule_files_before['clothes_dryer'] != schedule_files_after['clothes_dryer'])
594
+ assert(schedule_files_before['clothes_washer'] != schedule_files_after['clothes_washer'])
595
+ assert(schedule_files_before['cooking_range'] != schedule_files_after['cooking_range'])
596
+ assert(schedule_files_before['dishwasher'] != schedule_files_after['dishwasher'])
597
+
598
+ assert_equal(schedule_files_before['clothes_dryer'].sum, schedule_files_after['clothes_dryer'].sum)
599
+ assert_equal(schedule_files_before['clothes_washer'].sum, schedule_files_after['clothes_washer'].sum)
600
+ assert_equal(schedule_files_before['cooking_range'].sum, schedule_files_after['cooking_range'].sum)
601
+ assert_equal(schedule_files_before['dishwasher'].sum, schedule_files_after['dishwasher'].sum)
602
+ end
603
+ end