honeybee-openstudio 2.10.4 → 2.12.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +1 -0
- data/honeybee-openstudio.gemspec +1 -1
- data/lib/files/Honeybee.rb +28 -17
- data/lib/files/urbanopt_Gemfile +1 -1
- data/lib/honeybee.rb +1 -0
- data/lib/honeybee/_defaults/model.json +278 -175
- data/lib/honeybee/_defaults/simulation-parameter.json +1 -1
- data/lib/honeybee/load/daylight.rb +42 -0
- data/lib/measures/from_honeybee_model/measure.rb +23 -0
- data/lib/to_openstudio.rb +1 -0
- data/lib/to_openstudio/geometry/room.rb +6 -0
- data/lib/to_openstudio/hvac/Model.hvac.rb +124 -166
- data/lib/to_openstudio/hvac/template.rb +10 -2
- data/lib/to_openstudio/load/daylight.rb +100 -0
- data/lib/to_openstudio/model.rb +64 -4
- data/lib/to_openstudio/schedule/fixed_interval.rb +146 -30
- data/lib/to_openstudio/schedule/ruleset.rb +2 -1
- metadata +10 -93
@@ -35,6 +35,14 @@ require 'to_openstudio/model_object'
|
|
35
35
|
|
36
36
|
module Honeybee
|
37
37
|
class TemplateHVAC
|
38
|
+
@@vintage_mapper = {
|
39
|
+
DOE_Ref_Pre_1980: 'DOE Ref Pre-1980',
|
40
|
+
DOE_Ref_1980_2004: 'DOE Ref 1980-2004',
|
41
|
+
ASHRAE_2004: '90.1-2004',
|
42
|
+
ASHRAE_2007: '90.1-2007',
|
43
|
+
ASHRAE_2010: '90.1-2010',
|
44
|
+
ASHRAE_2013: '90.1-2013'
|
45
|
+
}
|
38
46
|
|
39
47
|
def to_openstudio(openstudio_model, room_ids)
|
40
48
|
|
@@ -47,9 +55,9 @@ module Honeybee
|
|
47
55
|
|
48
56
|
# make the standard applier
|
49
57
|
if @hash[:vintage]
|
50
|
-
standard = Standard.build(@hash[:vintage])
|
58
|
+
standard = Standard.build(@@vintage_mapper[@hash[:vintage].to_sym])
|
51
59
|
else
|
52
|
-
standard = Standard.build(hvac_defaults[:vintage][:default])
|
60
|
+
standard = Standard.build(@@vintage_mapper[hvac_defaults[:vintage][:default].to_sym])
|
53
61
|
end
|
54
62
|
|
55
63
|
# get the default equipment type
|
@@ -0,0 +1,100 @@
|
|
1
|
+
# *******************************************************************************
|
2
|
+
# Honeybee OpenStudio Gem, Copyright (c) 2020, Alliance for Sustainable
|
3
|
+
# Energy, LLC, Ladybug Tools LLC and other contributors. All rights reserved.
|
4
|
+
#
|
5
|
+
# Redistribution and use in source and binary forms, with or without
|
6
|
+
# modification, are permitted provided that the following conditions are met:
|
7
|
+
#
|
8
|
+
# (1) Redistributions of source code must retain the above copyright notice,
|
9
|
+
# this list of conditions and the following disclaimer.
|
10
|
+
#
|
11
|
+
# (2) Redistributions in binary form must reproduce the above copyright notice,
|
12
|
+
# this list of conditions and the following disclaimer in the documentation
|
13
|
+
# and/or other materials provided with the distribution.
|
14
|
+
#
|
15
|
+
# (3) Neither the name of the copyright holder nor the names of any contributors
|
16
|
+
# may be used to endorse or promote products derived from this software without
|
17
|
+
# specific prior written permission from the respective party.
|
18
|
+
#
|
19
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
|
20
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
21
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
22
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
|
23
|
+
# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
|
24
|
+
# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
25
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
26
|
+
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
27
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
28
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
29
|
+
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
30
|
+
# *******************************************************************************
|
31
|
+
|
32
|
+
require 'honeybee/load/daylight'
|
33
|
+
|
34
|
+
require 'to_openstudio/model_object'
|
35
|
+
|
36
|
+
module Honeybee
|
37
|
+
class DaylightingControl
|
38
|
+
|
39
|
+
def find_existing_openstudio_object(openstudio_model, parent_space_name)
|
40
|
+
dl_cntrl_name = parent_space_name + '_Daylighting'
|
41
|
+
model_dl_cntrl = openstudio_model.getDaylightingControlByName(dl_cntrl_name)
|
42
|
+
return model_dl_cntrl.get unless model_dl_cntrl.empty?
|
43
|
+
nil
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_openstudio(openstudio_model, parent_zone, parent_space)
|
47
|
+
# create daylighting control openstudio object and set identifier
|
48
|
+
os_dl_control = OpenStudio::Model::DaylightingControl.new(openstudio_model)
|
49
|
+
space_name = parent_space.name
|
50
|
+
unless space_name.empty?
|
51
|
+
os_dl_control.setName(parent_space.name.get + '_Daylighting')
|
52
|
+
end
|
53
|
+
os_dl_control.setSpace(parent_space)
|
54
|
+
parent_zone.setPrimaryDaylightingControl(os_dl_control)
|
55
|
+
|
56
|
+
# assign the position of the sensor point
|
57
|
+
os_dl_control.setPositionXCoordinate(@hash[:sensor_position][0])
|
58
|
+
os_dl_control.setPositionYCoordinate(@hash[:sensor_position][1])
|
59
|
+
os_dl_control.setPositionZCoordinate(@hash[:sensor_position][2])
|
60
|
+
|
61
|
+
# assign the illuminance setpoint if it exists
|
62
|
+
if @hash[:illuminance_setpoint]
|
63
|
+
os_dl_control.setIlluminanceSetpoint(@hash[:illuminance_setpoint])
|
64
|
+
else
|
65
|
+
os_dl_control.setIlluminanceSetpoint(defaults[:illuminance_setpoint][:default])
|
66
|
+
end
|
67
|
+
|
68
|
+
# assign power fraction if it exists
|
69
|
+
if @hash[:min_power_input]
|
70
|
+
os_dl_control.setMinimumInputPowerFractionforContinuousDimmingControl(@hash[:min_power_input])
|
71
|
+
else
|
72
|
+
os_dl_control.setMinimumInputPowerFractionforContinuousDimmingControl(defaults[:min_power_input][:default])
|
73
|
+
end
|
74
|
+
|
75
|
+
# assign light output fraction if it exists
|
76
|
+
if @hash[:min_power_input]
|
77
|
+
os_dl_control.setMinimumLightOutputFractionforContinuousDimmingControl(@hash[:min_light_output])
|
78
|
+
else
|
79
|
+
os_dl_control.setMinimumLightOutputFractionforContinuousDimmingControl(defaults[:min_light_output][:default])
|
80
|
+
end
|
81
|
+
|
82
|
+
# set whether the lights go off when they reach their minimum
|
83
|
+
if @hash[:off_at_minimum]
|
84
|
+
os_dl_control.setLightingControlType('Continuous/Off')
|
85
|
+
else
|
86
|
+
os_dl_control.setLightingControlType('Continuous')
|
87
|
+
end
|
88
|
+
|
89
|
+
# set the fraction of the zone lights that are dimmed
|
90
|
+
if @hash[:control_fraction]
|
91
|
+
parent_zone.setFractionofZoneControlledbyPrimaryDaylightingControl(@hash[:control_fraction])
|
92
|
+
else
|
93
|
+
parent_zone.setFractionofZoneControlledbyPrimaryDaylightingControl(defaults[:control_fraction][:default])
|
94
|
+
end
|
95
|
+
|
96
|
+
os_dl_control
|
97
|
+
end
|
98
|
+
|
99
|
+
end #DaylightingControl
|
100
|
+
end #Honeybee
|
data/lib/to_openstudio/model.rb
CHANGED
@@ -34,9 +34,38 @@ require 'honeybee/model'
|
|
34
34
|
require 'openstudio'
|
35
35
|
|
36
36
|
module Honeybee
|
37
|
+
|
38
|
+
def self.write_schedule_csv(schedule_csv_dir, schedule_csv)
|
39
|
+
filename = schedule_csv[:filename]
|
40
|
+
columns = schedule_csv[:columns]
|
41
|
+
if !columns.empty?
|
42
|
+
n = columns[0].size
|
43
|
+
path = File.join(schedule_csv_dir, filename)
|
44
|
+
File.open(path, 'w') do |file|
|
45
|
+
(0...n).each do |i|
|
46
|
+
row = []
|
47
|
+
columns.each do |column|
|
48
|
+
row << column[i]
|
49
|
+
end
|
50
|
+
file.puts row.join(',')
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
37
56
|
class Model
|
38
57
|
|
39
58
|
attr_reader :openstudio_model
|
59
|
+
attr_reader :schedule_csv_dir, :include_datetimes, :schedule_csvs
|
60
|
+
|
61
|
+
# if a schedule csv dir is specified then ScheduleFixedIntervalAbridged objects
|
62
|
+
# will be translated to ScheduleFile objects instead of ScheduleFixedInterval
|
63
|
+
# the optional schedule_csv_include_datetimes argument controls whether schedule csv
|
64
|
+
# files include a first column of date times for verification
|
65
|
+
def set_schedule_csv_dir(schedule_csv_dir, include_datetimes = false)
|
66
|
+
@schedule_csv_dir = schedule_csv_dir
|
67
|
+
@include_datetimes = include_datetimes
|
68
|
+
end
|
40
69
|
|
41
70
|
# convert to openstudio model, clears errors and warnings
|
42
71
|
def to_openstudio_model(openstudio_model=nil, log_report=true)
|
@@ -99,7 +128,7 @@ module Honeybee
|
|
99
128
|
create_schedule_type_limits(@hash[:properties][:energy][:schedule_type_limits])
|
100
129
|
end
|
101
130
|
if @hash[:properties][:energy][:schedules]
|
102
|
-
create_schedules(@hash[:properties][:energy][:schedules])
|
131
|
+
create_schedules(@hash[:properties][:energy][:schedules], false, true)
|
103
132
|
end
|
104
133
|
|
105
134
|
if log_report
|
@@ -283,7 +312,32 @@ module Honeybee
|
|
283
312
|
end
|
284
313
|
end
|
285
314
|
|
286
|
-
def create_schedules(schedule_dicts, check_existing=false)
|
315
|
+
def create_schedules(schedule_dicts, check_existing=false, check_leap_year=true)
|
316
|
+
|
317
|
+
# clear out schedule_csvs
|
318
|
+
@schedule_csvs = {}
|
319
|
+
|
320
|
+
if check_leap_year
|
321
|
+
is_leap_year = :unknown
|
322
|
+
schedule_dicts.each do |schedule|
|
323
|
+
# set is leap year = true in case start date has 3 integers
|
324
|
+
this_leap_year = false
|
325
|
+
if schedule[:start_date] && schedule[:start_date][2]
|
326
|
+
this_leap_year = true
|
327
|
+
end
|
328
|
+
if is_leap_year == :unknown
|
329
|
+
is_leap_year = this_leap_year
|
330
|
+
elsif is_leap_year != this_leap_year
|
331
|
+
raise("Mixed leap year information.")
|
332
|
+
end
|
333
|
+
end
|
334
|
+
|
335
|
+
if is_leap_year != :unknown
|
336
|
+
year_description = openstudio_model.getYearDescription
|
337
|
+
year_description.setIsLeapYear(is_leap_year)
|
338
|
+
end
|
339
|
+
end
|
340
|
+
|
287
341
|
schedule_dicts.each do |schedule|
|
288
342
|
# check if there's already a schedule in the model with the identifier
|
289
343
|
add_obj = true
|
@@ -305,9 +359,15 @@ module Honeybee
|
|
305
359
|
else
|
306
360
|
raise("Unknown schedule type #{schedule_type}.")
|
307
361
|
end
|
308
|
-
schedule_object.to_openstudio(@openstudio_model)
|
362
|
+
schedule_object.to_openstudio(@openstudio_model, @schedule_csv_dir, @include_datetimes, @schedule_csvs)
|
309
363
|
end
|
310
364
|
end
|
365
|
+
|
366
|
+
# write schedule csvs
|
367
|
+
@schedule_csvs.each_value do |schedule_csv|
|
368
|
+
Honeybee.write_schedule_csv(@schedule_csv_dir, schedule_csv)
|
369
|
+
end
|
370
|
+
|
311
371
|
end
|
312
372
|
|
313
373
|
def create_program_types(program_dicts, check_existing=false)
|
@@ -343,7 +403,7 @@ module Honeybee
|
|
343
403
|
end
|
344
404
|
@@standards[:schedules].each do |schedule|
|
345
405
|
if schedule[:identifier] == 'Always On'
|
346
|
-
create_schedules([schedule], true)
|
406
|
+
create_schedules([schedule], true, false)
|
347
407
|
end
|
348
408
|
end
|
349
409
|
|
@@ -42,26 +42,60 @@ module Honeybee
|
|
42
42
|
nil
|
43
43
|
end
|
44
44
|
|
45
|
-
def to_openstudio(openstudio_model)
|
45
|
+
def to_openstudio(openstudio_model, schedule_csv_dir = nil, include_datetimes = nil, schedule_csvs = nil)
|
46
|
+
if schedule_csv_dir
|
47
|
+
to_schedule_file(openstudio_model, schedule_csv_dir, include_datetimes, schedule_csvs)
|
48
|
+
else
|
49
|
+
to_schedule_fixed_interval(openstudio_model)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
def start_month
|
54
|
+
if @hash[:start_date]
|
55
|
+
return @hash[:start_date][0]
|
56
|
+
end
|
57
|
+
defaults[:start_date][:default][0]
|
58
|
+
end
|
59
|
+
|
60
|
+
def start_day
|
61
|
+
if @hash[:start_date]
|
62
|
+
return @hash[:start_date][1]
|
63
|
+
end
|
64
|
+
defaults[:start_date][:default][1]
|
65
|
+
end
|
66
|
+
|
67
|
+
def interpolate
|
68
|
+
if @hash[:interpolate]
|
69
|
+
return @hash[:interpolate]
|
70
|
+
end
|
71
|
+
defaults[:interpolate][:default]
|
72
|
+
end
|
73
|
+
|
74
|
+
def timestep
|
75
|
+
if @hash[:timestep]
|
76
|
+
return @hash[:timestep]
|
77
|
+
end
|
78
|
+
defaults[:timestep][:default]
|
79
|
+
end
|
80
|
+
|
81
|
+
def placeholder_value
|
82
|
+
if @hash[:placeholder_value]
|
83
|
+
return @hash[:placeholder_value]
|
84
|
+
end
|
85
|
+
defaults[:placeholder_value][:default]
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_schedule_fixed_interval(openstudio_model)
|
46
89
|
# create the new schedule
|
47
90
|
os_fi_schedule = OpenStudio::Model::ScheduleFixedInterval.new(openstudio_model)
|
48
91
|
os_fi_schedule.setName(@hash[:identifier])
|
49
92
|
|
50
93
|
# assign start date
|
51
|
-
|
52
|
-
|
53
|
-
os_fi_schedule.setStartDay(@hash[:start_date][1])
|
54
|
-
else
|
55
|
-
os_fi_schedule.setStartMonth(defaults[:start_date][:default][0])
|
56
|
-
os_fi_schedule.setStartDay(defaults[:start_date][:default][1])
|
57
|
-
end
|
94
|
+
os_fi_schedule.setStartMonth(start_month)
|
95
|
+
os_fi_schedule.setStartDay(start_day)
|
58
96
|
|
59
97
|
# assign the interpolate value
|
60
|
-
|
61
|
-
os_fi_schedule.setInterpolatetoTimestep(@hash[:interpolate])
|
62
|
-
else
|
63
|
-
os_fi_schedule.setInterpolatetoTimestep(defaults[:interpolate][:default])
|
64
|
-
end
|
98
|
+
os_fi_schedule.setInterpolatetoTimestep(interpolate)
|
65
99
|
|
66
100
|
# assign the schedule type limit
|
67
101
|
if @hash[:schedule_type_limit]
|
@@ -73,32 +107,114 @@ module Honeybee
|
|
73
107
|
end
|
74
108
|
|
75
109
|
# assign the timestep
|
76
|
-
|
77
|
-
|
78
|
-
interval_length = 60 / timestep
|
79
|
-
os_fi_schedule.setIntervalLength(interval_length)
|
80
|
-
else
|
81
|
-
timestep = defaults[:timestep][:default]
|
82
|
-
interval_length = 60 / timestep
|
83
|
-
os_fi_schedule.setIntervalLength(interval_length)
|
84
|
-
end
|
110
|
+
interval_length = 60 / timestep
|
111
|
+
os_fi_schedule.setIntervalLength(interval_length)
|
85
112
|
openstudio_interval_length = OpenStudio::Time.new(0, 0, interval_length)
|
86
113
|
|
87
114
|
# assign the values as a timeseries
|
88
115
|
year_description = openstudio_model.getYearDescription
|
116
|
+
start_date = year_description.makeDate(start_month, start_day)
|
117
|
+
timeseries = OpenStudio::TimeSeries.new(start_date, openstudio_interval_length, OpenStudio.createVector(@hash[:values]), '')
|
118
|
+
os_fi_schedule.setTimeSeries(timeseries)
|
89
119
|
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
120
|
+
os_fi_schedule
|
121
|
+
end
|
122
|
+
|
123
|
+
def to_schedule_file(openstudio_model, schedule_csv_dir, include_datetimes, schedule_csvs)
|
124
|
+
|
125
|
+
# in order to combine schedules in the same csv file they must have the same key
|
126
|
+
schedule_key = "#{@hash[:identifier]}_#{start_month}_#{start_day}_#{timestep}"
|
94
127
|
|
95
|
-
|
128
|
+
# get start and end date times
|
129
|
+
yd = openstudio_model.getYearDescription
|
130
|
+
date_time = OpenStudio::DateTime.new(yd.makeDate(1, 1), OpenStudio::Time.new(0,0,0))
|
131
|
+
start_date_time = OpenStudio::DateTime.new(yd.makeDate(start_month, start_day), OpenStudio::Time.new(0,0,0))
|
132
|
+
end_date_time = OpenStudio::DateTime.new(yd.makeDate(12, 31), OpenStudio::Time.new(1,0,0))
|
96
133
|
|
134
|
+
# get timestep
|
135
|
+
interval_length = 60 / timestep
|
136
|
+
dt = OpenStudio::Time.new(0, 0, interval_length, 0)
|
137
|
+
|
138
|
+
# get values and date times
|
97
139
|
values = @hash[:values]
|
98
|
-
|
99
|
-
|
140
|
+
num_values = values.size
|
141
|
+
i_values = 0
|
142
|
+
padded_values = []
|
143
|
+
date_times = []
|
144
|
+
pv = placeholder_value
|
100
145
|
|
101
|
-
|
146
|
+
while date_time < end_date_time
|
147
|
+
date = date_time.date
|
148
|
+
time = date_time.time
|
149
|
+
date_times << "#{date.dayOfMonth} #{date.monthOfYear.valueName} #{time.hours.to_s.rjust(2,'0')}:#{time.minutes.to_s.rjust(2,'0')}"
|
150
|
+
|
151
|
+
if date_time < start_date_time
|
152
|
+
padded_values << pv
|
153
|
+
elsif i_values < num_values
|
154
|
+
padded_values << values[i_values]
|
155
|
+
i_values += 1
|
156
|
+
else
|
157
|
+
padded_values << pv
|
158
|
+
end
|
159
|
+
|
160
|
+
date_time += dt
|
161
|
+
end
|
162
|
+
|
163
|
+
|
164
|
+
# find or create the schedule csv object which will hold the filename and columns
|
165
|
+
filename = nil
|
166
|
+
columns = nil
|
167
|
+
os_external_file = nil
|
168
|
+
schedule_csv = schedule_csvs[schedule_key]
|
169
|
+
if schedule_csv.nil?
|
170
|
+
# file name to write
|
171
|
+
filename = "#{@hash[:identifier]}.csv".gsub(' ', '_')
|
172
|
+
|
173
|
+
# columns of data
|
174
|
+
columns = []
|
175
|
+
if include_datetimes
|
176
|
+
columns << ['Date Times'].concat(date_times)
|
177
|
+
end
|
178
|
+
|
179
|
+
# schedule csv file must exist even though it has no content yet
|
180
|
+
path = File.join(schedule_csv_dir, filename)
|
181
|
+
if !File.exist?(path)
|
182
|
+
File.open(path, 'w') {|f| f.puts ''}
|
183
|
+
end
|
184
|
+
|
185
|
+
# get the external file which points to the schedule csv file
|
186
|
+
os_external_file = OpenStudio::Model::ExternalFile.getExternalFile(openstudio_model, filename)
|
187
|
+
os_external_file = os_external_file.get
|
188
|
+
|
189
|
+
schedule_csv = {filename: filename, columns: columns, os_external_file: os_external_file}
|
190
|
+
schedule_csvs[schedule_key] = schedule_csv
|
191
|
+
else
|
192
|
+
filename = schedule_csv[:filename]
|
193
|
+
columns = schedule_csv[:columns]
|
194
|
+
os_external_file = schedule_csv[:os_external_file]
|
195
|
+
end
|
196
|
+
|
197
|
+
# insert the padded_values to write later
|
198
|
+
columns << [@hash[:identifier]].concat(padded_values)
|
199
|
+
|
200
|
+
# create the schedule file
|
201
|
+
column = columns.size # 1 based index
|
202
|
+
rowsToSkip = 1
|
203
|
+
os_schedule_file = OpenStudio::Model::ScheduleFile.new(os_external_file, column, rowsToSkip)
|
204
|
+
os_schedule_file.setName(@hash[:identifier])
|
205
|
+
os_schedule_file.setInterpolatetoTimestep(interpolate)
|
206
|
+
os_schedule_file.setMinutesperItem(interval_length.to_s)
|
207
|
+
|
208
|
+
# assign the schedule type limit
|
209
|
+
if @hash[:schedule_type_limit]
|
210
|
+
schedule_type_limit = openstudio_model.getScheduleTypeLimitsByName(@hash[:schedule_type_limit])
|
211
|
+
unless schedule_type_limit.empty?
|
212
|
+
schedule_type_limit_object = schedule_type_limit.get
|
213
|
+
os_schedule_file.setScheduleTypeLimits(schedule_type_limit_object)
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
217
|
+
os_schedule_file
|
102
218
|
end
|
103
219
|
|
104
220
|
end #ScheduleFixedIntervalAbridged
|
@@ -42,7 +42,8 @@ module Honeybee
|
|
42
42
|
nil
|
43
43
|
end
|
44
44
|
|
45
|
-
def to_openstudio(openstudio_model)
|
45
|
+
def to_openstudio(openstudio_model, schedule_csv_dir = nil, include_datetimes = nil, schedule_csvs = nil)
|
46
|
+
|
46
47
|
# create openstudio schedule ruleset object
|
47
48
|
os_sch_ruleset = OpenStudio::Model::ScheduleRuleset.new(openstudio_model)
|
48
49
|
os_sch_ruleset.setName(@hash[:identifier])
|