openstudio-standards 0.1.11 → 0.1.12
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.
- checksums.yaml +4 -4
- data/data/standards/OpenStudio_Standards.xlsx +0 -0
- data/data/standards/OpenStudio_Standards_climate_zone_sets.json +96 -0
- data/data/standards/OpenStudio_Standards_climate_zones.json +96 -0
- data/data/standards/OpenStudio_Standards_construction_properties.json +11424 -0
- data/data/standards/OpenStudio_Standards_construction_sets.json +1746 -24
- data/data/standards/OpenStudio_Standards_constructions.json +409 -0
- data/data/standards/OpenStudio_Standards_curve_biquadratics.json +160 -0
- data/data/standards/OpenStudio_Standards_curve_quadratics.json +165 -0
- data/data/standards/OpenStudio_Standards_entryways.json +191 -0
- data/data/standards/OpenStudio_Standards_exterior_lighting.json +964 -0
- data/data/standards/OpenStudio_Standards_exterior_lighting_assumptions.json +191 -0
- data/data/standards/OpenStudio_Standards_ground_temperatures.json +11424 -0
- data/data/standards/OpenStudio_Standards_illuminated_parking_area.json +157 -0
- data/data/standards/OpenStudio_Standards_materials.json +2539 -745
- data/data/standards/OpenStudio_Standards_motors.json +420 -0
- data/data/standards/OpenStudio_Standards_parking.json +157 -0
- data/data/standards/OpenStudio_Standards_prototype_inputs.json +4410 -10
- data/data/standards/OpenStudio_Standards_schedules.json +13756 -8383
- data/data/standards/OpenStudio_Standards_space_types.json +8593 -907
- data/data/standards/OpenStudio_Standards_standards.json +9 -0
- data/data/standards/OpenStudio_Standards_templates.json +24 -0
- data/data/standards/OpenStudio_Standards_unitary_acs.json +924 -0
- data/data/standards/manage_OpenStudio_Standards.rb +1 -1
- data/lib/openstudio-standards/btap/btap.rb +0 -1
- data/lib/openstudio-standards/btap/compliance.rb +2 -5
- data/lib/openstudio-standards/btap/economics.rb +16 -16
- data/lib/openstudio-standards/btap/envelope.rb +1 -1
- data/lib/openstudio-standards/btap/equest.rb +7 -7
- data/lib/openstudio-standards/btap/fileio.rb +2 -2
- data/lib/openstudio-standards/btap/geometry.rb +1 -1
- data/lib/openstudio-standards/btap/measures.rb +16 -16
- data/lib/openstudio-standards/btap/mpc.rb +18 -18
- data/lib/openstudio-standards/btap/schedules.rb +35 -2
- data/lib/openstudio-standards/btap/simmanager.rb +1 -1
- data/lib/openstudio-standards/btap/spaceloads.rb +1 -1
- data/lib/openstudio-standards/btap/vintagizer.rb +1 -1
- data/lib/openstudio-standards/prototypes/Prototype.Model.elevators.rb +218 -0
- data/lib/openstudio-standards/prototypes/Prototype.Model.exterior_lights.rb +399 -0
- data/lib/openstudio-standards/prototypes/Prototype.Model.hvac.rb +2 -2
- data/lib/openstudio-standards/prototypes/Prototype.Model.rb +237 -0
- data/lib/openstudio-standards/prototypes/Prototype.Model.swh.rb +536 -0
- data/lib/openstudio-standards/standards/Standards.AirLoopHVAC.rb +6 -0
- data/lib/openstudio-standards/standards/Standards.Model.rb +249 -10
- data/lib/openstudio-standards/standards/Standards.SpaceType.rb +5 -5
- data/lib/openstudio-standards/standards/Standards.ThermalZone.rb +161 -0
- data/lib/openstudio-standards/utilities/simulation.rb +6 -4
- data/lib/openstudio-standards/version.rb +1 -1
- metadata +223 -204
- data/lib/openstudio-standards/btap/os_lib_schedules.rb +0 -677
@@ -1,677 +0,0 @@
|
|
1
|
-
# *********************************************************************
|
2
|
-
# * Copyright (c) 2008-2015, Natural Resources Canada
|
3
|
-
# * All rights reserved.
|
4
|
-
# *
|
5
|
-
# * This library is free software; you can redistribute it and/or
|
6
|
-
# * modify it under the terms of the GNU Lesser General Public
|
7
|
-
# * License as published by the Free Software Foundation; either
|
8
|
-
# * version 2.1 of the License, or (at your option) any later version.
|
9
|
-
# *
|
10
|
-
# * This library is distributed in the hope that it will be useful,
|
11
|
-
# * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
12
|
-
# * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
13
|
-
# * Lesser General Public License for more details.
|
14
|
-
# *
|
15
|
-
# * You should have received a copy of the GNU Lesser General Public
|
16
|
-
# * License along with this library; if not, write to the Free Software
|
17
|
-
# * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
18
|
-
# **********************************************************************/
|
19
|
-
|
20
|
-
|
21
|
-
require "#{File.dirname(__FILE__)}/btap"
|
22
|
-
|
23
|
-
|
24
|
-
module OsLib_Schedules
|
25
|
-
#This method creates a simple schedule and returns a ruleset schedule with a basic profile.
|
26
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
27
|
-
#@param model [OpenStudio::model::Model] A model object
|
28
|
-
#@param options [String]
|
29
|
-
#@return [OpenStudio::Model::ScheduleRuleset] the schedule ruleset
|
30
|
-
def OsLib_Schedules.createSimpleSchedule(model, options = {})
|
31
|
-
|
32
|
-
defaults = {
|
33
|
-
"name" => nil,
|
34
|
-
"winterTimeValuePairs" => {24.0 => 0.0},
|
35
|
-
"summerTimeValuePairs" => {24.0 => 1.0},
|
36
|
-
"defaultTimeValuePairs" => {24.0 => 1.0},
|
37
|
-
}
|
38
|
-
|
39
|
-
# merge user inputs with defaults
|
40
|
-
options = defaults.merge(options)
|
41
|
-
|
42
|
-
#ScheduleRuleset
|
43
|
-
sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
|
44
|
-
if name
|
45
|
-
sch_ruleset.setName(options["name"])
|
46
|
-
end
|
47
|
-
|
48
|
-
#Winter Design Day
|
49
|
-
winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
50
|
-
sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
|
51
|
-
winter_dsn_day = sch_ruleset.winterDesignDaySchedule
|
52
|
-
winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
|
53
|
-
options["winterTimeValuePairs"].each do |k,v|
|
54
|
-
hour = k.truncate
|
55
|
-
min = ((k - hour)*60).to_i
|
56
|
-
winter_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0),v)
|
57
|
-
end
|
58
|
-
|
59
|
-
#Summer Design Day
|
60
|
-
summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
61
|
-
sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
|
62
|
-
summer_dsn_day = sch_ruleset.summerDesignDaySchedule
|
63
|
-
summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
|
64
|
-
options["summerTimeValuePairs"].each do |k,v|
|
65
|
-
hour = k.truncate
|
66
|
-
min = ((k - hour)*60).to_i
|
67
|
-
summer_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0),v)
|
68
|
-
end
|
69
|
-
|
70
|
-
#All Days
|
71
|
-
default_day = sch_ruleset.defaultDaySchedule
|
72
|
-
default_day.setName("#{sch_ruleset.name} Schedule Week Day")
|
73
|
-
options["defaultTimeValuePairs"].each do |k,v|
|
74
|
-
hour = k.truncate
|
75
|
-
min = ((k - hour)*60).to_i
|
76
|
-
default_day.addValue(OpenStudio::Time.new(0, hour, min, 0),v)
|
77
|
-
end
|
78
|
-
|
79
|
-
result = sch_ruleset
|
80
|
-
return result
|
81
|
-
|
82
|
-
end #end of OsLib_Schedules.createSimpleSchedule
|
83
|
-
|
84
|
-
#This method finds the maximum profile value for a schedule and returns a min and max value.
|
85
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
86
|
-
#@param model [OpenStudio::model::Model] A model object
|
87
|
-
#@param schedule [Object]
|
88
|
-
#@return [Hash] a hash of min an max values "min":5.0, "max":3.0
|
89
|
-
def OsLib_Schedules.getMinMaxAnnualProfileValue(model, schedule)
|
90
|
-
|
91
|
-
# gather profiles
|
92
|
-
profiles = []
|
93
|
-
defaultProfile = schedule.to_ScheduleRuleset.get.defaultDaySchedule
|
94
|
-
profiles << defaultProfile
|
95
|
-
rules = schedule.scheduleRules
|
96
|
-
rules.each do |rule|
|
97
|
-
profiles << rule.daySchedule
|
98
|
-
end
|
99
|
-
|
100
|
-
# test profiles
|
101
|
-
min = nil
|
102
|
-
max = nil
|
103
|
-
profiles.each do |profile|
|
104
|
-
profile.values.each do |value|
|
105
|
-
if min.nil?
|
106
|
-
min = value
|
107
|
-
else
|
108
|
-
if min > value then min = value end
|
109
|
-
end
|
110
|
-
if max.nil?
|
111
|
-
max = value
|
112
|
-
else
|
113
|
-
if max < value then max = value end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
|
-
result = {"min" => min, "max" => max} # this doesn't include summer and winter design day
|
119
|
-
return result
|
120
|
-
|
121
|
-
end #end of OsLib_Schedules.getMaxAnnualProfileValue
|
122
|
-
|
123
|
-
#This method finds the maximum profile value for a schedule and returns the schedule.
|
124
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
125
|
-
#@param model [OpenStudio::model::Model] A model object
|
126
|
-
#@param schedule [Object]
|
127
|
-
#@param double [Float]
|
128
|
-
#@param modificationType [String]
|
129
|
-
#@return [Object] a schedule
|
130
|
-
def OsLib_Schedules.simpleScheduleValueAdjust(model,schedule,double, modificationType = "Multiplier")# can increase/decrease by percentage or static value
|
131
|
-
|
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" or modificationType == "Percentage" # percentage was used early on but Multiplier is preferable
|
151
|
-
profile.addValue(times[i],value*double)
|
152
|
-
end
|
153
|
-
if modificationType == "Sum" or 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
|
-
|
163
|
-
end #end of OsLib_Schedules.getMaxAnnualProfileValue
|
164
|
-
#This method finds the maximum profile value for a schedule and returns a schedule .
|
165
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
166
|
-
#@param model [OpenStudio::model::Model] A model object
|
167
|
-
#@param schedule [Object]
|
168
|
-
#@param valueTestDouble [Float]
|
169
|
-
#@param passDouble [Float]
|
170
|
-
#@param failDouble [Float]
|
171
|
-
#@param floorDouble [Float]
|
172
|
-
#@param modificationType [String]
|
173
|
-
#@return [Object] a schedule
|
174
|
-
def OsLib_Schedules.conditionalScheduleValueAdjust(model,schedule,valueTestDouble,passDouble,failDouble, floorDouble,modificationType = "Multiplier")# can increase/decrease by percentage or static value
|
175
|
-
# todo - add in design days, maybe as optional argument
|
176
|
-
# give option to clone or not
|
177
|
-
# gather profiles
|
178
|
-
profiles = []
|
179
|
-
defaultProfile = schedule.to_ScheduleRuleset.get.defaultDaySchedule
|
180
|
-
profiles << defaultProfile
|
181
|
-
rules = schedule.scheduleRules
|
182
|
-
rules.each do |rule|
|
183
|
-
profiles << rule.daySchedule
|
184
|
-
end
|
185
|
-
|
186
|
-
# alter profiles
|
187
|
-
profiles.each do |profile|
|
188
|
-
times = profile.times
|
189
|
-
i = 0
|
190
|
-
|
191
|
-
profile.values.each do |value|
|
192
|
-
|
193
|
-
# run test on this value
|
194
|
-
if value < valueTestDouble
|
195
|
-
double = passDouble
|
196
|
-
else
|
197
|
-
double = failDouble
|
198
|
-
end
|
199
|
-
|
200
|
-
# skip if value is floor or less
|
201
|
-
next if value <= floorDouble
|
202
|
-
|
203
|
-
if modificationType == "Multiplier"
|
204
|
-
profile.addValue(times[i],[value*double,floorDouble].max) #take the max of the floor or resulting value
|
205
|
-
end
|
206
|
-
if modificationType == "Sum"
|
207
|
-
profile.addValue(times[i],[value+double,floorDouble].max) #take the max of the floor or resulting value
|
208
|
-
end
|
209
|
-
i += 1
|
210
|
-
|
211
|
-
end
|
212
|
-
end
|
213
|
-
|
214
|
-
result = schedule
|
215
|
-
return result
|
216
|
-
|
217
|
-
end #end of OsLib_Schedules.getMaxAnnualProfileValue
|
218
|
-
|
219
|
-
|
220
|
-
#This method merges multiple schedules into one using load or other value to weight each schedules influence on the merge and returns a Merge schedule or denominator.
|
221
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
222
|
-
#@param model [OpenStudio::model::Model] A model object
|
223
|
-
#@param scheduleWeighHash [String]
|
224
|
-
#@return [Hash] a hash of the mergedSchedule [Object] and denominator [Object] "mergedSchedule":sch_ruleset, "denominator":denominator
|
225
|
-
def OsLib_Schedules.weightedMergeScheduleRulesets(model, scheduleWeighHash)
|
226
|
-
|
227
|
-
# WARNING NOT READY FOR GENERAL USE YET - this doesn't do anything with rules yet, just winter, summer, and default profile
|
228
|
-
|
229
|
-
# get denominator for weight
|
230
|
-
denominator = 0
|
231
|
-
scheduleWeighHash.each do |schedule,weight|
|
232
|
-
denominator += weight
|
233
|
-
end
|
234
|
-
|
235
|
-
# create new schedule
|
236
|
-
sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
|
237
|
-
sch_ruleset.setName("Merged Schedule") # todo - make this optional user argument
|
238
|
-
|
239
|
-
# create winter design day profile
|
240
|
-
winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
241
|
-
sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
|
242
|
-
winter_dsn_day = sch_ruleset.winterDesignDaySchedule
|
243
|
-
winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
|
244
|
-
|
245
|
-
# create summer design day profile
|
246
|
-
summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
247
|
-
sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
|
248
|
-
summer_dsn_day = sch_ruleset.summerDesignDaySchedule
|
249
|
-
summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
|
250
|
-
|
251
|
-
# create default profile
|
252
|
-
default_day = sch_ruleset.defaultDaySchedule
|
253
|
-
default_day.setName("#{sch_ruleset.name} Schedule Week Day")
|
254
|
-
|
255
|
-
# hash of schedule rules
|
256
|
-
rulesHash = {} # mon, tue, wed, thur, fri, sat, sun, startDate, endDate
|
257
|
-
# to avoid stacking order issues across schedules, I may need to make a rule for each day of the week for each date range
|
258
|
-
|
259
|
-
scheduleWeighHash.each do |schedule,weight|
|
260
|
-
|
261
|
-
# populate winter design day profile
|
262
|
-
oldWinterProfile = schedule.to_ScheduleRuleset.get.winterDesignDaySchedule
|
263
|
-
times_final = summer_dsn_day.times
|
264
|
-
i = 0
|
265
|
-
valueUpdatedArray = []
|
266
|
-
# loop through times already in profile and update values
|
267
|
-
until i > times_final.size - 1
|
268
|
-
value = oldWinterProfile.getValue(times_final[i])*weight/denominator
|
269
|
-
starting_value = winter_dsn_day.getValue(times_final[i])
|
270
|
-
winter_dsn_day.addValue(times_final[i],value + starting_value)
|
271
|
-
valueUpdatedArray << times_final[i]
|
272
|
-
i += 1
|
273
|
-
end
|
274
|
-
# loop through any new times unique to the current old profile to be merged
|
275
|
-
j = 0
|
276
|
-
times = oldWinterProfile.times
|
277
|
-
values = oldWinterProfile.values
|
278
|
-
until j > times.size - 1
|
279
|
-
if not valueUpdatedArray.include? times[j]
|
280
|
-
value = values[j]*weight/denominator
|
281
|
-
starting_value = winter_dsn_day.getValue(times[j])
|
282
|
-
winter_dsn_day.addValue(times[j],value+starting_value)
|
283
|
-
end
|
284
|
-
j += 1
|
285
|
-
end
|
286
|
-
|
287
|
-
# populate summer design day profile
|
288
|
-
oldSummerProfile = schedule.to_ScheduleRuleset.get.summerDesignDaySchedule
|
289
|
-
times_final = summer_dsn_day.times
|
290
|
-
i = 0
|
291
|
-
valueUpdatedArray = []
|
292
|
-
# loop through times already in profile and update values
|
293
|
-
until i > times_final.size - 1
|
294
|
-
value = oldSummerProfile.getValue(times_final[i])*weight/denominator
|
295
|
-
starting_value = summer_dsn_day.getValue(times_final[i])
|
296
|
-
summer_dsn_day.addValue(times_final[i],value + starting_value)
|
297
|
-
valueUpdatedArray << times_final[i]
|
298
|
-
i += 1
|
299
|
-
end
|
300
|
-
# loop through any new times unique to the current old profile to be merged
|
301
|
-
j = 0
|
302
|
-
times = oldSummerProfile.times
|
303
|
-
values = oldSummerProfile.values
|
304
|
-
until j > times.size - 1
|
305
|
-
if not valueUpdatedArray.include? times[j]
|
306
|
-
value = values[j]*weight/denominator
|
307
|
-
starting_value = summer_dsn_day.getValue(times[j])
|
308
|
-
summer_dsn_day.addValue(times[j],value+starting_value)
|
309
|
-
end
|
310
|
-
j += 1
|
311
|
-
end
|
312
|
-
|
313
|
-
# populate default profile
|
314
|
-
oldDefaultProfile = schedule.to_ScheduleRuleset.get.defaultDaySchedule
|
315
|
-
times_final = default_day.times
|
316
|
-
i = 0
|
317
|
-
valueUpdatedArray = []
|
318
|
-
# loop through times already in profile and update values
|
319
|
-
until i > times_final.size - 1
|
320
|
-
value = oldDefaultProfile.getValue(times_final[i])*weight/denominator
|
321
|
-
starting_value = default_day.getValue(times_final[i])
|
322
|
-
default_day.addValue(times_final[i],value + starting_value)
|
323
|
-
valueUpdatedArray << times_final[i]
|
324
|
-
i += 1
|
325
|
-
end
|
326
|
-
# loop through any new times unique to the current old profile to be merged
|
327
|
-
j = 0
|
328
|
-
times = oldDefaultProfile.times
|
329
|
-
values = oldDefaultProfile.values
|
330
|
-
until j > times.size - 1
|
331
|
-
if not valueUpdatedArray.include? times[j]
|
332
|
-
value = values[j]*weight/denominator
|
333
|
-
starting_value = default_day.getValue(times[j])
|
334
|
-
default_day.addValue(times[j],value+starting_value)
|
335
|
-
end
|
336
|
-
j += 1
|
337
|
-
end
|
338
|
-
|
339
|
-
# create rules
|
340
|
-
|
341
|
-
# gather data for rule profiles
|
342
|
-
|
343
|
-
# populate rule profiles
|
344
|
-
|
345
|
-
end
|
346
|
-
|
347
|
-
result = {"mergedSchedule" => sch_ruleset, "denominator" => denominator}
|
348
|
-
return result
|
349
|
-
|
350
|
-
end #end of OsLib_Schedules.weightedMergeScheduleRulesets
|
351
|
-
|
352
|
-
|
353
|
-
#This method will create a new schedule using absolute velocity of existing schedule and returns a new schedule.
|
354
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
355
|
-
#@param model [OpenStudio::model::Model] A model object
|
356
|
-
#@param schedule [Object]
|
357
|
-
#@return [Object] NewSchedule
|
358
|
-
def OsLib_Schedules.scheduleFromRateOfChange(model, schedule)
|
359
|
-
|
360
|
-
# clone source schedule
|
361
|
-
newSchedule = schedule.clone(model)
|
362
|
-
newSchedule.setName("#{schedule.name} - Rate of Change")
|
363
|
-
newSchedule = newSchedule.to_ScheduleRuleset.get
|
364
|
-
|
365
|
-
# create array of all profiles to change. This includes summer, winter, default, and rules
|
366
|
-
profiles = []
|
367
|
-
profiles << newSchedule.winterDesignDaySchedule
|
368
|
-
profiles << newSchedule.summerDesignDaySchedule
|
369
|
-
profiles << newSchedule.defaultDaySchedule
|
370
|
-
|
371
|
-
# time values may need
|
372
|
-
endProfileTime = OpenStudio::Time.new(0, 24, 0, 0)
|
373
|
-
hourBumpTime = OpenStudio::Time.new(0, 1, 0, 0)
|
374
|
-
oneHourLeftTime = OpenStudio::Time.new(0, 23, 0, 0)
|
375
|
-
|
376
|
-
rules = newSchedule.scheduleRules
|
377
|
-
rules.each do |rule|
|
378
|
-
profiles << rule.daySchedule
|
379
|
-
end
|
380
|
-
|
381
|
-
profiles.uniq.each do |profile|
|
382
|
-
times = profile.times
|
383
|
-
values = profile.values
|
384
|
-
|
385
|
-
i = 0
|
386
|
-
valuesIntermediate = []
|
387
|
-
timesIntermediate = []
|
388
|
-
until i == (values.size)
|
389
|
-
if i == 0
|
390
|
-
valuesIntermediate << 0.0
|
391
|
-
if times[i] > hourBumpTime
|
392
|
-
timesIntermediate << times[i] - hourBumpTime
|
393
|
-
if times[i+1].nil?
|
394
|
-
timeStepValue = endProfileTime.hours + endProfileTime.minutes/60 - times[i].hours - times[i].minutes/60
|
395
|
-
else
|
396
|
-
timeStepValue = times[i+1].hours + times[i+1].minutes/60 - times[i].hours - times[i].minutes/60
|
397
|
-
end
|
398
|
-
valuesIntermediate << (values[i+1].to_f - values[i].to_f ).abs/(timeStepValue*2)
|
399
|
-
end
|
400
|
-
timesIntermediate << times[i]
|
401
|
-
elsif i == (values.size - 1)
|
402
|
-
if times[times.size - 2] < oneHourLeftTime
|
403
|
-
timesIntermediate << times[times.size - 2] + hourBumpTime# this should be the second to last time
|
404
|
-
timeStepValue = times[i-1].hours + times[i-1].minutes/60 - times[i-2].hours - times[i-2].minutes/60
|
405
|
-
valuesIntermediate << (values[i-1].to_f - values[i-2].to_f ).abs/(timeStepValue*2)
|
406
|
-
end
|
407
|
-
valuesIntermediate << 0.0
|
408
|
-
timesIntermediate << times[i] # this should be the last time
|
409
|
-
else
|
410
|
-
# get value multiplier based on how many hours it is spread over
|
411
|
-
timeStepValue = times[i].hours + times[i].minutes/60 - times[i-1].hours - times[i-1].minutes/60
|
412
|
-
valuesIntermediate << (values[i].to_f - values[i - 1].to_f ).abs/timeStepValue
|
413
|
-
timesIntermediate << times[i]
|
414
|
-
end
|
415
|
-
i += 1
|
416
|
-
end
|
417
|
-
|
418
|
-
# delete all profile values
|
419
|
-
profile.clearValues
|
420
|
-
|
421
|
-
i = 0
|
422
|
-
until i == (timesIntermediate.size)
|
423
|
-
if i == (timesIntermediate.size - 1)
|
424
|
-
profile.addValue(timesIntermediate[i],valuesIntermediate[i].to_f)
|
425
|
-
else
|
426
|
-
profile.addValue(timesIntermediate[i],valuesIntermediate[i].to_f)
|
427
|
-
end
|
428
|
-
i += 1
|
429
|
-
end
|
430
|
-
|
431
|
-
end
|
432
|
-
|
433
|
-
# 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)
|
434
|
-
|
435
|
-
result = newSchedule
|
436
|
-
return result
|
437
|
-
|
438
|
-
end #end of OsLib_Schedules.createSimpleSchedule
|
439
|
-
|
440
|
-
# create a complex ruleset schedule
|
441
|
-
#This method will take 4 variables and return them as an array.
|
442
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
443
|
-
#@param model [OpenStudio::model::Model] A model object
|
444
|
-
#@param options [Object]
|
445
|
-
#@return [Object] schedule ruleset
|
446
|
-
def OsLib_Schedules.createComplexSchedule(model, options = {})
|
447
|
-
|
448
|
-
defaults = {
|
449
|
-
"name" => nil,
|
450
|
-
"default_day" => ["always_on",[24.0,1.0]]
|
451
|
-
}
|
452
|
-
|
453
|
-
# merge user inputs with defaults
|
454
|
-
options = defaults.merge(options)
|
455
|
-
|
456
|
-
#ScheduleRuleset
|
457
|
-
sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(model)
|
458
|
-
if name
|
459
|
-
sch_ruleset.setName(options["name"])
|
460
|
-
end
|
461
|
-
|
462
|
-
#Winter Design Day
|
463
|
-
unless options["winter_design_day"].nil?
|
464
|
-
winter_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
465
|
-
sch_ruleset.setWinterDesignDaySchedule(winter_dsn_day)
|
466
|
-
winter_dsn_day = sch_ruleset.winterDesignDaySchedule
|
467
|
-
winter_dsn_day.setName("#{sch_ruleset.name} Winter Design Day")
|
468
|
-
options["winter_design_day"].each do |data_pair|
|
469
|
-
hour = data_pair[0].truncate
|
470
|
-
min = ((data_pair[0] - hour)*60).to_i
|
471
|
-
winter_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0),data_pair[1])
|
472
|
-
end
|
473
|
-
end
|
474
|
-
|
475
|
-
#Summer Design Day
|
476
|
-
unless options["summer_design_day"].nil?
|
477
|
-
summer_dsn_day = OpenStudio::Model::ScheduleDay.new(model)
|
478
|
-
sch_ruleset.setSummerDesignDaySchedule(summer_dsn_day)
|
479
|
-
summer_dsn_day = sch_ruleset.summerDesignDaySchedule
|
480
|
-
summer_dsn_day.setName("#{sch_ruleset.name} Summer Design Day")
|
481
|
-
options["summer_design_day"].each do |data_pair|
|
482
|
-
hour = data_pair[0].truncate
|
483
|
-
min = ((data_pair[0] - hour)*60).to_i
|
484
|
-
summer_dsn_day.addValue(OpenStudio::Time.new(0, hour, min, 0),data_pair[1])
|
485
|
-
end
|
486
|
-
end
|
487
|
-
|
488
|
-
#Default Day
|
489
|
-
default_day = sch_ruleset.defaultDaySchedule
|
490
|
-
default_day.setName("#{sch_ruleset.name} #{options["default_day"][0]}")
|
491
|
-
default_data_array = options["default_day"]
|
492
|
-
default_data_array.delete_at(0)
|
493
|
-
default_data_array.each do |data_pair|
|
494
|
-
hour = data_pair[0].truncate
|
495
|
-
min = ((data_pair[0] - hour)*60).to_i
|
496
|
-
default_day.addValue(OpenStudio::Time.new(0, hour, min, 0),data_pair[1])
|
497
|
-
end
|
498
|
-
|
499
|
-
#Rules
|
500
|
-
unless options["rules"].nil?
|
501
|
-
options["rules"].each do |data_array|
|
502
|
-
rule = OpenStudio::Model::ScheduleRule.new(sch_ruleset)
|
503
|
-
rule.setName("#{sch_ruleset.name} #{data_array[0]} Rule")
|
504
|
-
date_range = data_array[1].split("-")
|
505
|
-
start_date = date_range[0].split("/")
|
506
|
-
end_date = date_range[1].split("/")
|
507
|
-
rule.setStartDate(model.getYearDescription.makeDate(start_date[0].to_i,start_date[1].to_i))
|
508
|
-
rule.setEndDate(model.getYearDescription.makeDate(end_date[0].to_i,end_date[1].to_i))
|
509
|
-
days = data_array[2].split("/")
|
510
|
-
rule.setApplySunday(true) if days.include? "Sun"
|
511
|
-
rule.setApplyMonday(true) if days.include? "Mon"
|
512
|
-
rule.setApplyTuesday(true) if days.include? "Tue"
|
513
|
-
rule.setApplyWednesday(true) if days.include? "Wed"
|
514
|
-
rule.setApplyThursday(true) if days.include? "Thu"
|
515
|
-
rule.setApplyFriday(true) if days.include? "Fri"
|
516
|
-
rule.setApplySaturday(true) if days.include? "Sat"
|
517
|
-
day_schedule = rule.daySchedule
|
518
|
-
day_schedule.setName("#{sch_ruleset.name} #{data_array[0]}")
|
519
|
-
data_array.delete_at(0)
|
520
|
-
data_array.delete_at(0)
|
521
|
-
data_array.delete_at(0)
|
522
|
-
data_array.each do |data_pair|
|
523
|
-
hour = data_pair[0].truncate
|
524
|
-
min = ((data_pair[0] - hour)*60).to_i
|
525
|
-
day_schedule.addValue(OpenStudio::Time.new(0, hour, min, 0),data_pair[1])
|
526
|
-
end
|
527
|
-
end
|
528
|
-
end
|
529
|
-
|
530
|
-
result = sch_ruleset
|
531
|
-
return result
|
532
|
-
|
533
|
-
end #end of OsLib_Schedules.createComplexSchedule
|
534
|
-
|
535
|
-
#This method will add schedule type limits and return limit types.
|
536
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
537
|
-
#@param model [OpenStudio::model::Model] A model object
|
538
|
-
#@return [type_limits<Float>]
|
539
|
-
def OsLib_Schedules.addScheduleTypeLimits(model) # todo - make sure to add this new method to cofee when done
|
540
|
-
|
541
|
-
type_limits = {}
|
542
|
-
|
543
|
-
lightsScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
544
|
-
lightsScheduleTypeLimits.setName("Lights Schedule Type Limits")
|
545
|
-
lightsScheduleTypeLimits.setLowerLimitValue(0.0)
|
546
|
-
lightsScheduleTypeLimits.setUpperLimitValue(1.0)
|
547
|
-
lightsScheduleTypeLimits.setNumericType("Continuous")
|
548
|
-
lightsScheduleTypeLimits.setUnitType("Dimensionless")
|
549
|
-
type_limits["Lights"] = lightsScheduleTypeLimits
|
550
|
-
|
551
|
-
occupancyScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
552
|
-
occupancyScheduleTypeLimits.setName("Occupancy Schedule Type Limits")
|
553
|
-
occupancyScheduleTypeLimits.setLowerLimitValue(0.0)
|
554
|
-
occupancyScheduleTypeLimits.setUpperLimitValue(1.0)
|
555
|
-
occupancyScheduleTypeLimits.setNumericType("Continuous")
|
556
|
-
occupancyScheduleTypeLimits.setUnitType("Dimensionless")
|
557
|
-
type_limits["Occupancy"] = occupancyScheduleTypeLimits
|
558
|
-
|
559
|
-
peopleActivityScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
560
|
-
peopleActivityScheduleTypeLimits.setName("People Activity Type Limits")
|
561
|
-
peopleActivityScheduleTypeLimits.setLowerLimitValue(0.0)
|
562
|
-
#peopleActivityScheduleTypeLimits.setUpperLimitValue(1500.0)
|
563
|
-
peopleActivityScheduleTypeLimits.setNumericType("Continuous")
|
564
|
-
peopleActivityScheduleTypeLimits.setUnitType("ActivityLevel")
|
565
|
-
type_limits["People Activity"] = peopleActivityScheduleTypeLimits
|
566
|
-
|
567
|
-
equipmentScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
568
|
-
equipmentScheduleTypeLimits.setName("Equipment Schedule Type Limits")
|
569
|
-
equipmentScheduleTypeLimits.setLowerLimitValue(0.0)
|
570
|
-
equipmentScheduleTypeLimits.setUpperLimitValue(1.0)
|
571
|
-
equipmentScheduleTypeLimits.setNumericType("Continuous")
|
572
|
-
equipmentScheduleTypeLimits.setUnitType("Dimensionless")
|
573
|
-
type_limits["Equipment"] = equipmentScheduleTypeLimits
|
574
|
-
|
575
|
-
waterUseScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
576
|
-
waterUseScheduleTypeLimits.setName("Water Use Schedule Type Limits")
|
577
|
-
waterUseScheduleTypeLimits.setLowerLimitValue(0.0)
|
578
|
-
waterUseScheduleTypeLimits.setUpperLimitValue(1.0)
|
579
|
-
waterUseScheduleTypeLimits.setNumericType("Continuous")
|
580
|
-
waterUseScheduleTypeLimits.setUnitType("Dimensionless")
|
581
|
-
type_limits["Water Use"] = waterUseScheduleTypeLimits
|
582
|
-
|
583
|
-
elevatorsScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
584
|
-
elevatorsScheduleTypeLimits.setName("Elevators Schedule Type Limits")
|
585
|
-
elevatorsScheduleTypeLimits.setLowerLimitValue(0.0)
|
586
|
-
elevatorsScheduleTypeLimits.setUpperLimitValue(1.0)
|
587
|
-
elevatorsScheduleTypeLimits.setNumericType("Continuous")
|
588
|
-
elevatorsScheduleTypeLimits.setUnitType("Dimensionless")
|
589
|
-
type_limits["Elevators"] = elevatorsScheduleTypeLimits
|
590
|
-
|
591
|
-
processLoadsScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
592
|
-
processLoadsScheduleTypeLimits.setName("Process Loads Schedule Type Limits")
|
593
|
-
processLoadsScheduleTypeLimits.setLowerLimitValue(0.0)
|
594
|
-
processLoadsScheduleTypeLimits.setUpperLimitValue(1.0)
|
595
|
-
processLoadsScheduleTypeLimits.setNumericType("Continuous")
|
596
|
-
processLoadsScheduleTypeLimits.setUnitType("Dimensionless")
|
597
|
-
type_limits["Process Load"] = elevatorsScheduleTypeLimits
|
598
|
-
|
599
|
-
thermostatHeatingScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
600
|
-
thermostatHeatingScheduleTypeLimits.setName("Thermostat Heating Setpoint Schedule Type Limits")
|
601
|
-
thermostatHeatingScheduleTypeLimits.setLowerLimitValue(0.0)
|
602
|
-
thermostatHeatingScheduleTypeLimits.setUpperLimitValue(100.0)
|
603
|
-
thermostatHeatingScheduleTypeLimits.setNumericType("Continuous")
|
604
|
-
thermostatHeatingScheduleTypeLimits.setUnitType("Temperature")
|
605
|
-
type_limits["Thermostat Heating Setpoint"] = thermostatHeatingScheduleTypeLimits
|
606
|
-
|
607
|
-
temperatureScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
608
|
-
temperatureScheduleTypeLimits.setName("Thermostat Cooling Setpoint Schedule Type Limits")
|
609
|
-
temperatureScheduleTypeLimits.setLowerLimitValue(0.0)
|
610
|
-
temperatureScheduleTypeLimits.setUpperLimitValue(100.0)
|
611
|
-
temperatureScheduleTypeLimits.setNumericType("Continuous")
|
612
|
-
temperatureScheduleTypeLimits.setUnitType("Temperature")
|
613
|
-
type_limits["Thermostat Cooling Setpoint"] = temperatureScheduleTypeLimits
|
614
|
-
|
615
|
-
hvacOperationScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
616
|
-
hvacOperationScheduleTypeLimits.setName("HVAC Operation Schedule Type Limits")
|
617
|
-
hvacOperationScheduleTypeLimits.setLowerLimitValue(0)
|
618
|
-
hvacOperationScheduleTypeLimits.setUpperLimitValue(1)
|
619
|
-
hvacOperationScheduleTypeLimits.setNumericType("Discrete")
|
620
|
-
hvacOperationScheduleTypeLimits.setUnitType("Availability")
|
621
|
-
type_limits["HVAC Operation"] = hvacOperationScheduleTypeLimits
|
622
|
-
|
623
|
-
temperatureScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
624
|
-
temperatureScheduleTypeLimits.setName("Temperature Schedule Type Limits")
|
625
|
-
temperatureScheduleTypeLimits.setNumericType("Continuous")
|
626
|
-
temperatureScheduleTypeLimits.setUnitType("Temperature")
|
627
|
-
type_limits["Temperature"] = temperatureScheduleTypeLimits
|
628
|
-
|
629
|
-
fractionScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
630
|
-
fractionScheduleTypeLimits.setName("Fraction Schedule Type Limits")
|
631
|
-
fractionScheduleTypeLimits.setLowerLimitValue(0.0)
|
632
|
-
fractionScheduleTypeLimits.setUpperLimitValue(1.0)
|
633
|
-
fractionScheduleTypeLimits.setNumericType("Continuous")
|
634
|
-
fractionScheduleTypeLimits.setUnitType("Dimensionless")
|
635
|
-
type_limits["Fraction"] = fractionScheduleTypeLimits
|
636
|
-
|
637
|
-
dimensionlessScheduleTypeLimits = OpenStudio::Model::ScheduleTypeLimits.new(model)
|
638
|
-
dimensionlessScheduleTypeLimits.setName("Dimensionless Schedule Type Limits")
|
639
|
-
dimensionlessScheduleTypeLimits.setNumericType("Continuous")
|
640
|
-
dimensionlessScheduleTypeLimits.setUnitType("Dimensionless")
|
641
|
-
type_limits["Dimensionless"] = dimensionlessScheduleTypeLimits
|
642
|
-
|
643
|
-
return type_limits
|
644
|
-
|
645
|
-
end
|
646
|
-
|
647
|
-
#This method creates TimeSeries from ScheduleRuleset.
|
648
|
-
#@author phylroy.lopez@nrcan.gc.ca
|
649
|
-
#@param model [OpenStudio::model::Model] A model object
|
650
|
-
#@param schedule_ruleset [Object]
|
651
|
-
def OsLib_Schedules.create_timeseries_from_schedule_ruleset(model,schedule_ruleset)
|
652
|
-
|
653
|
-
yd = model.getYearDescription
|
654
|
-
start_date = yd.makeDate(1,1)
|
655
|
-
end_date = yd.makeDate(12,31)
|
656
|
-
|
657
|
-
values = OpenStudio::DoubleVector.new
|
658
|
-
day = OpenStudio::Time.new(1.0)
|
659
|
-
interval = OpenStudio::Time.new(1.0/48.0)
|
660
|
-
day_schedules = schedule_ruleset.to_ScheduleRuleset.get.getDaySchedules(start_date,end_date)
|
661
|
-
day_schedules.each do |day_schedule|
|
662
|
-
time = interval
|
663
|
-
while time < day
|
664
|
-
values << day_schedule.getValue(time)
|
665
|
-
time += interval
|
666
|
-
end
|
667
|
-
end
|
668
|
-
time_series = OpenStudio::TimeSeries.new(start_date, interval, OpenStudio::createVector(values), "")
|
669
|
-
end
|
670
|
-
|
671
|
-
# create ScheduleVariableInterval from TimeSeries
|
672
|
-
def OsLib_Schedules.create_schedule_variable_interval_from_time_series(model,time_series)
|
673
|
-
result = OpenStudio::Model::ScheduleInterval.fromTimeSeries(time_series, model).get
|
674
|
-
end
|
675
|
-
|
676
|
-
|
677
|
-
end
|