openstudio-extension 0.7.1 → 0.8.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/CHANGELOG.md +14 -0
- data/LICENSE.md +1 -1
- data/README.md +2 -0
- data/lib/openstudio/extension/runner.rb +12 -8
- data/lib/openstudio/extension/runner_config.rb +33 -6
- data/lib/openstudio/extension/version.rb +1 -1
- data/openstudio-extension.gemspec +6 -6
- metadata +15 -66
- data/lib/openstudio/extension/core/CreateResults.rb +0 -1033
- data/lib/openstudio/extension/core/check_air_sys_temps.rb +0 -160
- data/lib/openstudio/extension/core/check_calibration.rb +0 -125
- data/lib/openstudio/extension/core/check_cond_zns.rb +0 -54
- data/lib/openstudio/extension/core/check_domestic_hot_water.rb +0 -304
- data/lib/openstudio/extension/core/check_envelope_conductance.rb +0 -423
- data/lib/openstudio/extension/core/check_eui_by_end_use.rb +0 -132
- data/lib/openstudio/extension/core/check_eui_reasonableness.rb +0 -105
- data/lib/openstudio/extension/core/check_fan_pwr.rb +0 -68
- data/lib/openstudio/extension/core/check_internal_loads.rb +0 -363
- data/lib/openstudio/extension/core/check_mech_sys_capacity.rb +0 -196
- data/lib/openstudio/extension/core/check_mech_sys_efficiency.rb +0 -296
- data/lib/openstudio/extension/core/check_mech_sys_part_load_eff.rb +0 -434
- data/lib/openstudio/extension/core/check_mech_sys_type.rb +0 -109
- data/lib/openstudio/extension/core/check_part_loads.rb +0 -421
- data/lib/openstudio/extension/core/check_placeholder.rb +0 -45
- data/lib/openstudio/extension/core/check_plant_cap.rb +0 -93
- data/lib/openstudio/extension/core/check_plant_temps.rb +0 -129
- data/lib/openstudio/extension/core/check_plenum_loads.rb +0 -57
- data/lib/openstudio/extension/core/check_pump_pwr.rb +0 -78
- data/lib/openstudio/extension/core/check_sch_coord.rb +0 -211
- data/lib/openstudio/extension/core/check_schedules.rb +0 -281
- data/lib/openstudio/extension/core/check_simultaneous_heating_and_cooling.rb +0 -128
- data/lib/openstudio/extension/core/check_supply_air_and_thermostat_temp_difference.rb +0 -118
- data/lib/openstudio/extension/core/check_weather_files.rb +0 -102
- data/lib/openstudio/extension/core/deer_vintages.rb +0 -281
- data/lib/openstudio/extension/core/os_lib_aedg_measures.rb +0 -461
- data/lib/openstudio/extension/core/os_lib_constructions.rb +0 -353
- data/lib/openstudio/extension/core/os_lib_geometry.rb +0 -1169
- data/lib/openstudio/extension/core/os_lib_helper_methods.rb +0 -383
- data/lib/openstudio/extension/core/os_lib_hvac.rb +0 -2163
- data/lib/openstudio/extension/core/os_lib_lighting_and_equipment.rb +0 -184
- data/lib/openstudio/extension/core/os_lib_model_generation.rb +0 -3584
- data/lib/openstudio/extension/core/os_lib_model_simplification.rb +0 -1019
- data/lib/openstudio/extension/core/os_lib_outdoorair_and_infiltration.rb +0 -135
- data/lib/openstudio/extension/core/os_lib_reporting_qaqc.rb +0 -170
- data/lib/openstudio/extension/core/os_lib_schedules.rb +0 -933
@@ -1,135 +0,0 @@
|
|
1
|
-
# *******************************************************************************
|
2
|
-
# OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
|
3
|
-
# See also https://openstudio.net/license
|
4
|
-
# *******************************************************************************
|
5
|
-
|
6
|
-
module OsLib_OutdoorAirAndInfiltration
|
7
|
-
# delete any infiltration objects used in the model.
|
8
|
-
def self.eraseInfiltrationUsedInModel(model, runner)
|
9
|
-
# get space infiltration objects.
|
10
|
-
space_infiltration_objects = model.getSpaceInfiltrationDesignFlowRates.sort
|
11
|
-
|
12
|
-
# hash to hold schedules used for infiltration objects in the model
|
13
|
-
@infiltrationSchedulesHardAssigned = {}
|
14
|
-
|
15
|
-
def OsLib_OutdoorAirAndInfiltration.addScheduleToArrayAndRemove(space_infiltration_object)
|
16
|
-
# get schedule and add to hash
|
17
|
-
if !space_infiltration_object.isScheduleDefaulted
|
18
|
-
if !space_infiltration_object.schedule.empty?
|
19
|
-
schedule = space_infiltration_object.schedule.get
|
20
|
-
if @infiltrationSchedulesHardAssigned.key?(schedule)
|
21
|
-
@infiltrationSchedulesHardAssigned[schedule] = @infiltrationSchedulesHardAssigned[schedule] + 1
|
22
|
-
else
|
23
|
-
@infiltrationSchedulesHardAssigned[schedule] = 1
|
24
|
-
end
|
25
|
-
end
|
26
|
-
end
|
27
|
-
space_infiltration_object.remove
|
28
|
-
end
|
29
|
-
|
30
|
-
# remove space infiltration objects
|
31
|
-
number_removed = 0
|
32
|
-
number_left = 0
|
33
|
-
space_infiltration_objects.each do |space_infiltration_object|
|
34
|
-
opt_space_type = space_infiltration_object.spaceType
|
35
|
-
if opt_space_type.empty?
|
36
|
-
# add schedule if exists to array and remove object
|
37
|
-
OsLib_OutdoorAirAndInfiltration.addScheduleToArrayAndRemove(space_infiltration_object)
|
38
|
-
number_removed += 1
|
39
|
-
elsif !opt_space_type.get.spaces.empty?
|
40
|
-
# add schedule if exists to array and remove object
|
41
|
-
OsLib_OutdoorAirAndInfiltration.addScheduleToArrayAndRemove(space_infiltration_object)
|
42
|
-
number_removed += 1
|
43
|
-
else
|
44
|
-
number_left += 1
|
45
|
-
end
|
46
|
-
end
|
47
|
-
if number_removed > 0
|
48
|
-
runner.registerInfo("#{number_removed} infiltration objects were removed.")
|
49
|
-
end
|
50
|
-
if number_left > 0
|
51
|
-
runner.registerInfo("#{number_left} infiltration objects in unused space types were left in the model. They will not be altered.")
|
52
|
-
end
|
53
|
-
|
54
|
-
result = @infiltrationSchedulesHardAssigned.sort_by { |k, v| v }.reverse # want schedule with largest key first
|
55
|
-
return result
|
56
|
-
end
|
57
|
-
|
58
|
-
# create new infiltration def and apply it to all spaces throughout the entire building
|
59
|
-
def self.addSpaceInfiltrationDesignFlowRate(model, runner, objects, options = {})
|
60
|
-
# set defaults to use if user inputs not passed in
|
61
|
-
defaults = {
|
62
|
-
'nameSuffix' => ' - infiltration', # add this to object name for infiltration
|
63
|
-
'defaultBuildingSchedule' => nil, # this will set schedule set for selected object
|
64
|
-
'schedule' => nil, # this will hard assign a schedule
|
65
|
-
'setCalculationMethod' => nil, # should be string like setFlowerExteriorSurfaceArea
|
66
|
-
'valueForSelectedCalcMethod' => nil
|
67
|
-
}
|
68
|
-
|
69
|
-
# merge user inputs with defaults
|
70
|
-
options = defaults.merge(options)
|
71
|
-
building = model.getBuilding
|
72
|
-
newSpaceInfiltrationObjects = []
|
73
|
-
|
74
|
-
# set default building infiltration schedule if requested
|
75
|
-
if !options['defaultBuildingSchedule'].nil?
|
76
|
-
if !building.defaultScheduleSet.empty?
|
77
|
-
defaultScheduleSet = building.defaultScheduleSet.get
|
78
|
-
else
|
79
|
-
defaultScheduleSet = OpenStudio::Model::DefaultScheduleSet.new(model)
|
80
|
-
defaultScheduleSet.setName('Default Schedules')
|
81
|
-
building.setDefaultScheduleSet(defaultScheduleSet)
|
82
|
-
end
|
83
|
-
# set requested default schedule
|
84
|
-
defaultScheduleSet.setInfiltrationSchedule(options['defaultBuildingSchedule'])
|
85
|
-
end
|
86
|
-
|
87
|
-
# note: object should be the building, or an array of space and or space types
|
88
|
-
if objects == building
|
89
|
-
# if no default space type then add an empty one (to hold new space infiltration object)
|
90
|
-
if building.spaceType.empty?
|
91
|
-
new_default = OpenStudio::Model::SpaceType.new(model)
|
92
|
-
new_default.setName('Building Default Space Type')
|
93
|
-
building.setSpaceType(new_default)
|
94
|
-
runner.registerInfo("Adding a building default space type to hold space infiltration for spaces that previously didn't have a space type.")
|
95
|
-
end
|
96
|
-
|
97
|
-
# change objects to be all space types used in the model
|
98
|
-
objects = []
|
99
|
-
space_types = model.getSpaceTypes.sort
|
100
|
-
space_types.each do |space_type|
|
101
|
-
if !space_type.spaces.empty?
|
102
|
-
objects << space_type
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
|
-
|
107
|
-
# loop through objects
|
108
|
-
objects.each do |object|
|
109
|
-
# create the infiltration object and associate with space or space type
|
110
|
-
new_infil = OpenStudio::Model::SpaceInfiltrationDesignFlowRate.new(model)
|
111
|
-
newSpaceInfiltrationObjects << new_infil
|
112
|
-
eval("new_infil.#{options['setCalculationMethod']}(#{options['valueForSelectedCalcMethod']})")
|
113
|
-
if !object.to_SpaceType.empty?
|
114
|
-
new_infil.setSpaceType(object)
|
115
|
-
elsif !object.to_Space.empty?
|
116
|
-
new_infil.setSpace(object)
|
117
|
-
else
|
118
|
-
runner.registerWarning("#{object.name} isn't a space or a space type. Can't assign infiltration object to it.")
|
119
|
-
end
|
120
|
-
new_infil.setName("#{object.name} #{options['nameSuffix']}")
|
121
|
-
|
122
|
-
# set hard assigned schedule if requested
|
123
|
-
if options['schedule']
|
124
|
-
new_infil.setSchedule(options['schedule'])
|
125
|
-
end
|
126
|
-
|
127
|
-
if new_infil.schedule.empty?
|
128
|
-
runner.registerWarning("The new infiltration object for space type '#{object.name}' does not have a schedule. Assigning a default schedule set including an infiltration schedule to the space type or the building will address this.")
|
129
|
-
end
|
130
|
-
end
|
131
|
-
|
132
|
-
result = newSpaceInfiltrationObjects
|
133
|
-
return result
|
134
|
-
end
|
135
|
-
end
|
@@ -1,170 +0,0 @@
|
|
1
|
-
# *******************************************************************************
|
2
|
-
# OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
|
3
|
-
# See also https://openstudio.net/license
|
4
|
-
# *******************************************************************************
|
5
|
-
|
6
|
-
require 'json'
|
7
|
-
|
8
|
-
module OsLib_Reporting
|
9
|
-
# setup - get model, sql, and setup web assets path
|
10
|
-
def self.setup(runner)
|
11
|
-
results = {}
|
12
|
-
|
13
|
-
# get the last model
|
14
|
-
model = runner.lastOpenStudioModel
|
15
|
-
if model.empty?
|
16
|
-
runner.registerError('Cannot find last model.')
|
17
|
-
return false
|
18
|
-
end
|
19
|
-
model = model.get
|
20
|
-
|
21
|
-
# get the last idf
|
22
|
-
workspace = runner.lastEnergyPlusWorkspace
|
23
|
-
if workspace.empty?
|
24
|
-
runner.registerError('Cannot find last idf file.')
|
25
|
-
return false
|
26
|
-
end
|
27
|
-
workspace = workspace.get
|
28
|
-
|
29
|
-
# get the last sql file
|
30
|
-
sqlFile = runner.lastEnergyPlusSqlFile
|
31
|
-
if sqlFile.empty?
|
32
|
-
runner.registerError('Cannot find last sql file.')
|
33
|
-
return false
|
34
|
-
end
|
35
|
-
sqlFile = sqlFile.get
|
36
|
-
model.setSqlFile(sqlFile)
|
37
|
-
|
38
|
-
# populate hash to pass to measure
|
39
|
-
results[:model] = model
|
40
|
-
# results[:workspace] = workspace
|
41
|
-
results[:sqlFile] = sqlFile
|
42
|
-
results[:web_asset_path] = OpenStudio.getSharedResourcesPath / OpenStudio::Path.new('web_assets')
|
43
|
-
|
44
|
-
return results
|
45
|
-
end
|
46
|
-
|
47
|
-
# cleanup - prep html
|
48
|
-
def self.gen_html(html_in_path, web_asset_path, sections, name)
|
49
|
-
# instance variables for erb
|
50
|
-
@sections = sections
|
51
|
-
@name = name
|
52
|
-
|
53
|
-
# read in template
|
54
|
-
if File.exist?(html_in_path)
|
55
|
-
html_in_path = html_in_path
|
56
|
-
else
|
57
|
-
html_in_path = "#{File.dirname(__FILE__)}/report.html.erb"
|
58
|
-
end
|
59
|
-
html_in = ''
|
60
|
-
File.open(html_in_path, 'r') do |file|
|
61
|
-
html_in = file.read
|
62
|
-
end
|
63
|
-
|
64
|
-
# configure template with variable values
|
65
|
-
renderer = ERB.new(html_in)
|
66
|
-
html_out = renderer.result(binding)
|
67
|
-
|
68
|
-
# write html file
|
69
|
-
html_out_path = './report.html'
|
70
|
-
File.open(html_out_path, 'w') do |file|
|
71
|
-
file << html_out
|
72
|
-
# make sure data is written to the disk one way or the other
|
73
|
-
begin
|
74
|
-
file.fsync
|
75
|
-
rescue StandardError
|
76
|
-
file.flush
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
return html_out_path
|
81
|
-
end
|
82
|
-
|
83
|
-
# developer notes
|
84
|
-
# method below is custom version of standard OpenStudio results methods. It passes an array of sections vs. a single section.
|
85
|
-
# It doesn't use the model or SQL file. It just gets data form OpenStudio attributes passed in
|
86
|
-
# It doesn't have a name_only section since it doesn't populate user arguments
|
87
|
-
|
88
|
-
def self.sections_from_check_attributes(check_elems, runner)
|
89
|
-
# inspecting check attributes
|
90
|
-
# make single table with checks.
|
91
|
-
# make second table with flag description (with column for where it came from)
|
92
|
-
|
93
|
-
# array to hold sections
|
94
|
-
sections = []
|
95
|
-
|
96
|
-
# gather data for section
|
97
|
-
qaqc_check_summary = {}
|
98
|
-
qaqc_check_summary[:title] = 'List of Checks in Measure'
|
99
|
-
qaqc_check_summary[:header] = ['Name', 'Category', 'Flags', 'Description']
|
100
|
-
qaqc_check_summary[:data] = []
|
101
|
-
qaqc_check_summary[:data_color] = []
|
102
|
-
@qaqc_check_section = {}
|
103
|
-
@qaqc_check_section[:title] = 'QAQC Check Summary'
|
104
|
-
@qaqc_check_section[:tables] = [qaqc_check_summary]
|
105
|
-
|
106
|
-
# add sections to array
|
107
|
-
sections << @qaqc_check_section
|
108
|
-
|
109
|
-
# counter for flags thrown
|
110
|
-
num_flags = 0
|
111
|
-
|
112
|
-
check_elems.each do |check|
|
113
|
-
# gather data for section
|
114
|
-
qaqc_flag_details = {}
|
115
|
-
qaqc_flag_details[:title] = "List of Flags Triggered for #{check.valueAsAttributeVector.first.valueAsString}."
|
116
|
-
qaqc_flag_details[:header] = ['Flag Detail']
|
117
|
-
qaqc_flag_details[:data] = []
|
118
|
-
@qaqc_flag_section = {}
|
119
|
-
@qaqc_flag_section[:title] = check.valueAsAttributeVector.first.valueAsString.to_s
|
120
|
-
@qaqc_flag_section[:tables] = [qaqc_flag_details]
|
121
|
-
|
122
|
-
check_name = nil
|
123
|
-
check_cat = nil
|
124
|
-
check_desc = nil
|
125
|
-
flags = []
|
126
|
-
# loop through attributes (name,category,description,then optionally one or more flag attributes)
|
127
|
-
check.valueAsAttributeVector.each_with_index do |value, index|
|
128
|
-
if index == 0
|
129
|
-
check_name = value.valueAsString
|
130
|
-
elsif index == 1
|
131
|
-
check_cat = value.valueAsString
|
132
|
-
elsif index == 2
|
133
|
-
check_desc = value.valueAsString
|
134
|
-
else # should be flag
|
135
|
-
flags << value.valueAsString
|
136
|
-
qaqc_flag_details[:data] << [value.valueAsString]
|
137
|
-
runner.registerWarning("#{check_name} - #{value.valueAsString}")
|
138
|
-
num_flags += 1
|
139
|
-
end
|
140
|
-
end
|
141
|
-
|
142
|
-
# add row to table for this check
|
143
|
-
qaqc_check_summary[:data] << [check_name, check_cat, flags.size, check_desc]
|
144
|
-
|
145
|
-
# add info message for check if no flags found (this way user still knows what ran)
|
146
|
-
if check.valueAsAttributeVector.size < 4
|
147
|
-
runner.registerInfo("#{check_name} - no flags.")
|
148
|
-
end
|
149
|
-
|
150
|
-
# color cells based and add runner register values based on flag status
|
151
|
-
if !flags.empty?
|
152
|
-
qaqc_check_summary[:data_color] << ['', '', 'indianred', '']
|
153
|
-
runner.registerValue(check_name.downcase.tr(' ', '_'), flags.size, 'flags')
|
154
|
-
else
|
155
|
-
qaqc_check_summary[:data_color] << ['', '', 'lightgreen', '']
|
156
|
-
runner.registerValue(check_name.downcase.tr(' ', '_'), flags.size, 'flags')
|
157
|
-
end
|
158
|
-
|
159
|
-
# add table for this check if there are flags
|
160
|
-
if !qaqc_flag_details[:data].empty?
|
161
|
-
sections << @qaqc_flag_section
|
162
|
-
end
|
163
|
-
end
|
164
|
-
|
165
|
-
# add total flags registerValue
|
166
|
-
runner.registerValue('total_qaqc_flags', num_flags, 'flags')
|
167
|
-
|
168
|
-
return sections
|
169
|
-
end
|
170
|
-
end
|