-
Notifications
You must be signed in to change notification settings - Fork 15
/
measure.rb
229 lines (196 loc) · 11.3 KB
/
measure.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
# *******************************************************************************
# OpenStudio(R), Copyright (c) Alliance for Sustainable Energy, LLC.
# See also https://openstudio.net/license
# *******************************************************************************
require 'erb'
require 'json'
require "#{File.dirname(__FILE__)}/resources/os_lib_reporting_envelope_and_internal_loads_breakdown"
# start the measure
class EnvelopeAndInternalLoadBreakdown < OpenStudio::Ruleset::ReportingUserScript
# define the name that a user will see, this method may be deprecated as
# the display name in PAT comes from the name field in measure.xml
def name
return 'Envelope and Internal Load Breakdown'
end
# human readable description
def description
return 'Report provides annual and monthly views into heat gains and losses for envelope and internal loads.'
end
# human readable description of modeling approach
def modeler_description
return "It uses the following variables: Electric Equipment Total Heating Energy, Zone Lights Total Heating Energy, Zone, People Sensible Heating Energy, Surface Average Face Conduction Heat Transfer Energy, Surface Window Heat Gain Energy, Surface Window Heat Loss Energy, Zone Infiltration Sensible Heat Gain Energy, Zone Infiltration Sensible Heat Loss Energy. For Surface Average Face Conduction Heat Transfer Energy bin positive values as heat gain and negative values as heat loss.\n"
end
def possible_sections
# methods for sections in order that they will appear in report
result = []
# instead of hand populating, any methods with 'section' in the name will be added in the order they appear
all_sections = OsLib_ReportingHeatGainLoss.methods(false)
method_hash = {}
all_sections.each do |section|
next if !section.to_s.include? 'section'
method_hash[section.to_s] = OsLib_ReportingHeatGainLoss.method(section).source_location.last
end
# sort methods by location in file (this was not necessary when using Ruby 2.2.4)
result = method_hash.sort_by { |_key, value| value }.to_h.keys
result
end
# define the arguments that the user will input
def arguments(model = nil)
args = OpenStudio::Ruleset::OSArgumentVector.new
# # populate arguments
# possible_sections.each do |method_name|
# # get display name
# arg = OpenStudio::Ruleset::OSArgument.makeBoolArgument(method_name, true)
# display_name = eval("OsLib_ReportingHeatGainLoss.#{method_name}(nil,nil,nil,true)[:title]")
# arg.setDisplayName(display_name)
# arg.setDefaultValue(true)
# args << arg
# end
args
end
# add any outout variable requests here
def energyPlusOutputRequests(runner, user_arguments)
super(runner, user_arguments)
result = OpenStudio::IdfObjectVector.new
# monthly heat gain outputs
result << OpenStudio::IdfObject.load('Output:Variable,,Electric Equipment Total Heating Energy,monthly;').get
result << OpenStudio::IdfObject.load('Output:Variable,,Gas Equipment Total Heating Energy,monthly;').get
result << OpenStudio::IdfObject.load('Output:Variable,,Zone Lights Total Heating Energy,monthly;').get
result << OpenStudio::IdfObject.load('Output:Variable,,Zone People Sensible Heating Energy,monthly;').get
result << OpenStudio::IdfObject.load('Output:Variable,,Zone Infiltration Sensible Heat Gain Energy,monthly;').get
result << OpenStudio::IdfObject.load('Output:Variable,,Surface Window Heat Gain Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Cooling Load Increase Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Cooling Load Increase Due to Overheating Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Cooling Load Decrease Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation No Load Heat Addition Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Air System Heat Exchanger Total Cooling Energy,monthly;').get
# monthly heat loss outputs
result << OpenStudio::IdfObject.load('Output:Variable,,Zone Infiltration Sensible Heat Loss Energy,monthly;').get
result << OpenStudio::IdfObject.load('Output:Variable,,Surface Window Heat Loss Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Heating Load Increase Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Heating Load Increase Due to Overcooling Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Heating Load Decrease Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation No Load Heat Removal Energy,monthly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Air System Heat Exchanger Total Heating Energy,monthly;').get
#
# # diagnostic outputs
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Cooling Load Increase Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Cooling Load Increase Due to Overheating Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Cooling Load Decrease Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation No Load Heat Addition Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Air System Heat Exchanger Total Cooling Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Heating Load Increase Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Heating Load Increase Due to Overcooling Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation Heating Load Decrease Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Mechanical Ventilation No Load Heat Removal Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Air System Heat Exchanger Total Heating Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Site Outdoor Air Drybulb Temperature,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Site Outdoor Air Wetbulb Temperature,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Air System Fan Air Electric Energy,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Air System Outdoor Air Mass Flow Rate,hourly;').get
# result << OpenStudio::IdfObject.load('Output:Variable,,Zone Air Terminal Outdoor Air Volume Flow Rate,hourly;').get
# hourly outputs (will bin by hour to heat loss or gain and roll up to monthly, may break out by surface type)
result << OpenStudio::IdfObject.load('Output:Variable,,Surface Average Face Conduction Heat Transfer Energy,hourly;').get
result
end
# define what happens when the measure is run
def run(runner, user_arguments)
super(runner, user_arguments)
# get sql, model, and web assets
setup = OsLib_ReportingHeatGainLoss.setup(runner)
unless setup
return false
end
model = setup[:model]
# workspace = setup[:workspace]
sql_file = setup[:sqlFile]
web_asset_path = setup[:web_asset_path]
# # assign the user inputs to variables
# args = OsLib_HelperMethods.createRunVariables(runner, model, user_arguments, arguments)
# unless args
# return false
# end
# reporting final condition
runner.registerInitialCondition('Gathering data from EnergyPlus SQL file and OSM model.')
# pass measure display name to erb
@name = name
# create a array of sections to loop through in erb file
@sections = []
raw_sections = []
# generate data for requested sections
sections_made = 0
possible_sections.each do |method_name|
# next unless args[method_name]
section = false
eval("section = OsLib_ReportingHeatGainLoss.#{method_name}(model,sql_file,runner,false)")
display_name = eval("OsLib_ReportingHeatGainLoss.#{method_name}(nil,nil,nil,true)[:title]")
if section
raw_sections << section
sections_made += 1
# look for emtpy tables and warn if skipped because returned empty
section[:tables].each do |table|
if !table
runner.registerWarning("A table in #{display_name} section returned false and was skipped.")
section[:messages] = ["One or more tables in #{display_name} section returned false and was skipped."]
end
end
else
runner.registerWarning("#{display_name} section returned false and was skipped.")
section = {}
section[:title] = display_name.to_s
section[:tables] = []
section[:messages] = []
section[:messages] << "#{display_name} section returned false and was skipped."
raw_sections << section
end
rescue StandardError => e
display_name = eval("OsLib_ReportingHeatGainLoss.#{method_name}(nil,nil,nil,true)[:title]")
if display_name.nil? then display_name == method_name end
runner.registerWarning("#{display_name} section failed and was skipped because: #{e}. Detail on error follows.")
runner.registerWarning(e.backtrace.join("\n").to_s)
# add in section heading with message if section fails
section = eval("OsLib_ReportingHeatGainLoss.#{method_name}(nil,nil,nil,true)")
section[:messages] = []
section[:messages] << "#{display_name} section failed and was skipped because: #{e}. Detail on error follows."
section[:messages] << [e.backtrace.join("\n").to_s]
raw_sections << section
end
# reorganize section order so summaries are at top (1,3,0,2)
@sections << raw_sections[1]
@sections << raw_sections[3]
@sections << raw_sections[0]
@sections << raw_sections[2]
# read in template
html_in_path = "#{File.dirname(__FILE__)}/resources/report.html.erb"
if File.exist?(html_in_path)
html_in_path = html_in_path
else
html_in_path = "#{File.dirname(__FILE__)}/report.html.erb"
end
html_in = ''
File.open(html_in_path, 'r') do |file|
html_in = file.read
end
# configure template with variable values
renderer = ERB.new(html_in)
html_out = renderer.result(binding)
# write html file
html_out_path = './report.html'
File.open(html_out_path, 'w') do |file|
file << html_out
# make sure data is written to the disk one way or the other
begin
file.fsync
rescue StandardError
file.flush
end
end
# closing the sql file
sql_file.close
# reporting final condition
runner.registerFinalCondition("Generated report with #{sections_made} sections to #{html_out_path}.")
true
end
end
# this allows the measure to be use by the application
EnvelopeAndInternalLoadBreakdown.new.registerWithApplication