urbanopt-reporting 0.2.0 → 0.3.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/ISSUE_TEMPLATE/bug_report.md +19 -0
- data/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
- data/.github/pull_request_template.md +13 -0
- data/.rdoc_options +36 -0
- data/CHANGELOG.md +43 -1
- data/LICENSE.md +1 -1
- data/RDOC_MAIN.md +10 -0
- data/deploy_docs.sh +5 -0
- data/doc_templates/LICENSE.md +1 -1
- data/doc_templates/copyright_erb.txt +1 -1
- data/doc_templates/copyright_js.txt +1 -1
- data/doc_templates/copyright_ruby.txt +1 -1
- data/docs/.gitignore +3 -0
- data/docs/.vuepress/components/InnerJsonSchema.vue +76 -0
- data/docs/.vuepress/components/JsonSchema.vue +12 -0
- data/docs/.vuepress/components/ScenarioSchema.vue +12 -0
- data/docs/.vuepress/components/StaticLink.vue +8 -0
- data/docs/.vuepress/config.js +25 -0
- data/docs/.vuepress/highlight.js +8 -0
- data/docs/.vuepress/json-schema-deref-loader.js +22 -0
- data/docs/.vuepress/public/custom_rdoc_styles.css +78 -0
- data/docs/.vuepress/styles/palette.styl +1 -0
- data/docs/.vuepress/utils.js +17 -0
- data/docs/README.md +9 -0
- data/docs/package-lock.json +10018 -0
- data/docs/package.json +30 -0
- data/docs/schemas/scenario-schema.md +3 -0
- data/lib/measures/default_feature_reports/LICENSE.md +1 -1
- data/lib/measures/default_feature_reports/measure.rb +231 -87
- data/lib/measures/default_feature_reports/measure.xml +11 -11
- data/lib/measures/export_modelica_loads/LICENSE.md +27 -0
- data/lib/measures/export_modelica_loads/README.md +26 -0
- data/lib/measures/export_modelica_loads/README.md.erb +42 -0
- data/lib/measures/export_modelica_loads/docs/.gitkeep +0 -0
- data/lib/measures/export_modelica_loads/measure.rb +367 -0
- data/lib/measures/export_modelica_loads/measure.xml +92 -0
- data/lib/measures/export_modelica_loads/resources/report.html.in +13 -0
- data/lib/measures/export_time_series_modelica/LICENSE.md +1 -0
- data/lib/measures/export_time_series_modelica/README.md +59 -0
- data/lib/measures/export_time_series_modelica/README.md.erb +42 -0
- data/lib/measures/export_time_series_modelica/docs/.gitkeep +0 -0
- data/lib/measures/export_time_series_modelica/measure.rb +433 -0
- data/lib/measures/export_time_series_modelica/measure.xml +147 -0
- data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +399 -0
- data/lib/measures/export_time_series_modelica/resources/report.html.in +13 -0
- data/lib/urbanopt/reporting/default_reports/end_uses.rb +52 -38
- data/lib/urbanopt/reporting/default_reports/feature_report.rb +79 -8
- data/lib/urbanopt/reporting/default_reports/location.rb +11 -11
- data/lib/urbanopt/reporting/default_reports/program.rb +86 -86
- data/lib/urbanopt/reporting/default_reports/reporting_period.rb +98 -78
- data/lib/urbanopt/reporting/default_reports/scenario_report.rb +7 -4
- data/lib/urbanopt/reporting/default_reports/schema/scenario_csv_columns.txt +15 -0
- data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +108 -80
- data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +10 -10
- data/lib/urbanopt/reporting/version.rb +1 -1
- data/urbanopt-reporting-gem.gemspec +4 -4
- metadata +50 -13
@@ -3,8 +3,8 @@
|
|
3
3
|
<schema_version>3.0</schema_version>
|
4
4
|
<name>default_feature_reports</name>
|
5
5
|
<uid>9ee3135a-8070-4408-bfa1-b75fecf9dd4f</uid>
|
6
|
-
<version_id>
|
7
|
-
<version_modified>
|
6
|
+
<version_id>d4f5b2e2-f93d-4ce2-9c68-ed29714fdc0c</version_id>
|
7
|
+
<version_modified>20201208T230102Z</version_modified>
|
8
8
|
<xml_checksum>FB304155</xml_checksum>
|
9
9
|
<class_name>DefaultFeatureReports</class_name>
|
10
10
|
<display_name>DefaultFeatureReports</display_name>
|
@@ -126,17 +126,23 @@
|
|
126
126
|
<usage_type>test</usage_type>
|
127
127
|
<checksum>CC4BFFAF</checksum>
|
128
128
|
</file>
|
129
|
+
<file>
|
130
|
+
<filename>README.md</filename>
|
131
|
+
<filetype>md</filetype>
|
132
|
+
<usage_type>readme</usage_type>
|
133
|
+
<checksum>0B68E96D</checksum>
|
134
|
+
</file>
|
129
135
|
<file>
|
130
136
|
<filename>LICENSE.md</filename>
|
131
137
|
<filetype>md</filetype>
|
132
138
|
<usage_type>license</usage_type>
|
133
|
-
<checksum>
|
139
|
+
<checksum>BBD19F47</checksum>
|
134
140
|
</file>
|
135
141
|
<file>
|
136
142
|
<filename>default_feature_reports_test.rb</filename>
|
137
143
|
<filetype>rb</filetype>
|
138
144
|
<usage_type>test</usage_type>
|
139
|
-
<checksum>
|
145
|
+
<checksum>19681175</checksum>
|
140
146
|
</file>
|
141
147
|
<file>
|
142
148
|
<version>
|
@@ -147,13 +153,7 @@
|
|
147
153
|
<filename>measure.rb</filename>
|
148
154
|
<filetype>rb</filetype>
|
149
155
|
<usage_type>script</usage_type>
|
150
|
-
<checksum>
|
151
|
-
</file>
|
152
|
-
<file>
|
153
|
-
<filename>README.md</filename>
|
154
|
-
<filetype>md</filetype>
|
155
|
-
<usage_type>readme</usage_type>
|
156
|
-
<checksum>0B68E96D</checksum>
|
156
|
+
<checksum>48AEB753</checksum>
|
157
157
|
</file>
|
158
158
|
</files>
|
159
159
|
</measure>
|
@@ -0,0 +1,27 @@
|
|
1
|
+
OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC. All rights reserved.
|
2
|
+
|
3
|
+
Redistribution and use in source and binary forms, with or without modification, are permitted
|
4
|
+
provided that the following conditions are met:
|
5
|
+
|
6
|
+
(1) Redistributions of source code must retain the above copyright notice, this list of conditions
|
7
|
+
and the following disclaimer.
|
8
|
+
|
9
|
+
(2) Redistributions in binary form must reproduce the above copyright notice, this list of conditions
|
10
|
+
and the following disclaimer in the documentation and/or other materials provided with the distribution.
|
11
|
+
|
12
|
+
(3) Neither the name of the copyright holder nor the names of any contributors may be used to endorse
|
13
|
+
or promote products derived from this software without specific prior written permission from the
|
14
|
+
respective party.
|
15
|
+
|
16
|
+
(4) Other than as required in clauses (1) and (2), distributions in any form of modifications or other
|
17
|
+
derivative works may not use the "OpenStudio" trademark, "OS", "os", or any other confusingly similar
|
18
|
+
designation without specific prior written permission from Alliance for Sustainable Energy, LLC.
|
19
|
+
|
20
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
|
21
|
+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
22
|
+
PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER, THE UNITED STATES GOVERNMENT,
|
23
|
+
OR ANY CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
24
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
|
25
|
+
OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
26
|
+
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
27
|
+
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
@@ -0,0 +1,26 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
###### (Automatically generated documentation)
|
4
|
+
|
5
|
+
# Export Modelica Loads
|
6
|
+
|
7
|
+
## Description
|
8
|
+
Use the results from the EnergyPlus simulation to generate a load file for use in Modelica. This will create a MOS and a CSV file of the heating, cooling, and hot water loads.
|
9
|
+
|
10
|
+
## Modeler Description
|
11
|
+
|
12
|
+
|
13
|
+
## Measure Type
|
14
|
+
ReportingMeasure
|
15
|
+
|
16
|
+
## Taxonomy
|
17
|
+
|
18
|
+
|
19
|
+
## Arguments
|
20
|
+
|
21
|
+
|
22
|
+
|
23
|
+
|
24
|
+
This measure does not have any user arguments
|
25
|
+
|
26
|
+
|
@@ -0,0 +1,42 @@
|
|
1
|
+
<%#= README.md.erb is used to auto-generate README.md. %>
|
2
|
+
<%#= To manually maintain README.md throw away README.md.erb and manually edit README.md %>
|
3
|
+
###### (Automatically generated documentation)
|
4
|
+
|
5
|
+
# <%= name %>
|
6
|
+
|
7
|
+
## Description
|
8
|
+
<%= description %>
|
9
|
+
|
10
|
+
## Modeler Description
|
11
|
+
<%= modelerDescription %>
|
12
|
+
|
13
|
+
## Measure Type
|
14
|
+
<%= measureType %>
|
15
|
+
|
16
|
+
## Taxonomy
|
17
|
+
<%= taxonomy %>
|
18
|
+
|
19
|
+
## Arguments
|
20
|
+
|
21
|
+
<% arguments.each do |argument| %>
|
22
|
+
### <%= argument[:display_name] %>
|
23
|
+
<%= argument[:description] %>
|
24
|
+
**Name:** <%= argument[:name] %>,
|
25
|
+
**Type:** <%= argument[:type] %>,
|
26
|
+
**Units:** <%= argument[:units] %>,
|
27
|
+
**Required:** <%= argument[:required] %>,
|
28
|
+
**Model Dependent:** <%= argument[:model_dependent] %>
|
29
|
+
<% end %>
|
30
|
+
|
31
|
+
<% if arguments.size == 0 %>
|
32
|
+
<%= "This measure does not have any user arguments" %>
|
33
|
+
<% end %>
|
34
|
+
|
35
|
+
<% if outputs.size > 0 %>
|
36
|
+
## Outputs
|
37
|
+
<% output_names = [] %>
|
38
|
+
<% outputs.each do |output| %>
|
39
|
+
<% output_names << output[:display_name] %>
|
40
|
+
<% end %>
|
41
|
+
<%= output_names.join(", ") %>
|
42
|
+
<% end %>
|
File without changes
|
@@ -0,0 +1,367 @@
|
|
1
|
+
# *******************************************************************************
|
2
|
+
# OpenStudio(R), Copyright (c) 2008-2020, Alliance for Sustainable Energy, LLC.
|
3
|
+
# All rights reserved.
|
4
|
+
# Redistribution and use in source and binary forms, with or without
|
5
|
+
# modification, are permitted provided that the following conditions are met:
|
6
|
+
#
|
7
|
+
# (1) Redistributions of source code must retain the above copyright notice,
|
8
|
+
# this list of conditions and the following disclaimer.
|
9
|
+
#
|
10
|
+
# (2) Redistributions in binary form must reproduce the above copyright notice,
|
11
|
+
# this list of conditions and the following disclaimer in the documentation
|
12
|
+
# and/or other materials provided with the distribution.
|
13
|
+
#
|
14
|
+
# (3) Neither the name of the copyright holder nor the names of any contributors
|
15
|
+
# may be used to endorse or promote products derived from this software without
|
16
|
+
# specific prior written permission from the respective party.
|
17
|
+
#
|
18
|
+
# (4) Other than as required in clauses (1) and (2), distributions in any form
|
19
|
+
# of modifications or other derivative works may not use the "OpenStudio"
|
20
|
+
# trademark, "OS", "os", or any other confusingly similar designation without
|
21
|
+
# specific prior written permission from Alliance for Sustainable Energy, LLC.
|
22
|
+
#
|
23
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
|
24
|
+
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
|
25
|
+
# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
26
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
|
27
|
+
# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
|
28
|
+
# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
29
|
+
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
|
30
|
+
# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
31
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
32
|
+
# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
33
|
+
# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
34
|
+
# *******************************************************************************
|
35
|
+
|
36
|
+
require 'erb'
|
37
|
+
|
38
|
+
# start the measure
|
39
|
+
class ExportModelicaLoads < OpenStudio::Measure::ReportingMeasure
|
40
|
+
# human readable name
|
41
|
+
def name
|
42
|
+
# Measure name should be the title case of the class name.
|
43
|
+
return 'Export Modelica Loads'
|
44
|
+
end
|
45
|
+
|
46
|
+
def description
|
47
|
+
return 'Use the results from the EnergyPlus simulation to generate a load file for use in Modelica. This will create a MOS and a CSV file of the heating, cooling, and hot water loads.'
|
48
|
+
end
|
49
|
+
|
50
|
+
def modeler_description
|
51
|
+
return ''
|
52
|
+
end
|
53
|
+
|
54
|
+
def log(str)
|
55
|
+
puts "#{Time.now}: #{str}"
|
56
|
+
end
|
57
|
+
|
58
|
+
def arguments(_model)
|
59
|
+
args = OpenStudio::Measure::OSArgumentVector.new
|
60
|
+
|
61
|
+
# this measure does not require any user arguments, return an empty list
|
62
|
+
return args
|
63
|
+
end
|
64
|
+
|
65
|
+
# return a vector of IdfObject's to request EnergyPlus objects needed by the run method
|
66
|
+
def energyPlusOutputRequests(runner, user_arguments)
|
67
|
+
super(runner, user_arguments)
|
68
|
+
|
69
|
+
result = OpenStudio::IdfObjectVector.new
|
70
|
+
|
71
|
+
# To use the built-in error checking we need the model...
|
72
|
+
# get the last model and sql file
|
73
|
+
model = runner.lastOpenStudioModel
|
74
|
+
if model.empty?
|
75
|
+
runner.registerError('Cannot find last model.')
|
76
|
+
return false
|
77
|
+
end
|
78
|
+
model = model.get
|
79
|
+
|
80
|
+
# use the built-in error checking
|
81
|
+
if !runner.validateUserArguments(arguments(model), user_arguments)
|
82
|
+
return false
|
83
|
+
end
|
84
|
+
|
85
|
+
result << OpenStudio::IdfObject.load('Output:Variable,,Site Mains Water Temperature,hourly;').get
|
86
|
+
result << OpenStudio::IdfObject.load('Output:Variable,,Site Outdoor Air Drybulb Temperature,hourly;').get
|
87
|
+
result << OpenStudio::IdfObject.load('Output:Variable,,Site Outdoor Air Relative Humidity,hourly;').get
|
88
|
+
result << OpenStudio::IdfObject.load('Output:Meter,Cooling:Electricity,hourly;').get
|
89
|
+
result << OpenStudio::IdfObject.load('Output:Meter,Heating:Electricity,hourly;').get
|
90
|
+
result << OpenStudio::IdfObject.load('Output:Meter,Heating:Gas,hourly;').get
|
91
|
+
result << OpenStudio::IdfObject.load('Output:Meter,InteriorLights:Electricity,hourly;').get
|
92
|
+
result << OpenStudio::IdfObject.load('Output:Meter,Fans:Electricity,hourly;').get
|
93
|
+
result << OpenStudio::IdfObject.load('Output:Meter,InteriorEquipment:Electricity,hourly;').get # Joules
|
94
|
+
result << OpenStudio::IdfObject.load('Output:Meter,ExteriorLighting:Electricity,hourly;').get # Joules
|
95
|
+
result << OpenStudio::IdfObject.load('Output:Meter,Electricity:Facility,hourly;').get # Joules
|
96
|
+
result << OpenStudio::IdfObject.load('Output:Meter,Gas:Facility,hourly;').get # Joules
|
97
|
+
result << OpenStudio::IdfObject.load('Output:Meter,Heating:EnergyTransfer,hourly;').get # Joules
|
98
|
+
result << OpenStudio::IdfObject.load('Output:Meter,WaterSystems:EnergyTransfer,hourly;').get # Joules
|
99
|
+
# these variables are used for the modelica export.
|
100
|
+
result << OpenStudio::IdfObject.load('Output:Variable,*,Zone Predicted Sensible Load to Setpoint Heat Transfer Rate,hourly;').get # watts according to e+
|
101
|
+
result << OpenStudio::IdfObject.load('Output:Variable,*,Water Heater Total Demand Heat Transfer Rate,hourly;').get # Watts
|
102
|
+
|
103
|
+
return result
|
104
|
+
end
|
105
|
+
|
106
|
+
def extract_timeseries_into_matrix(sqlfile, data, variable_name, key_value = nil, default_if_empty=0)
|
107
|
+
log "Executing query for #{variable_name}"
|
108
|
+
column_name = variable_name
|
109
|
+
if key_value
|
110
|
+
ts = sqlfile.timeSeries('RUN PERIOD 1', 'Hourly', variable_name, key_value)
|
111
|
+
# ts = sqlfile.timeSeries('RUN PERIOD 1', 'Zone Timestep', variable_name, key_value)
|
112
|
+
column_name += "_#{key_value}"
|
113
|
+
else
|
114
|
+
ts = sqlfile.timeSeries('RUN PERIOD 1', 'Hourly', variable_name)
|
115
|
+
# ts = sqlfile.timeSeries('RUN PERIOD 1', 'Zone Timestep', variable_name)
|
116
|
+
end
|
117
|
+
log 'Iterating over timeseries'
|
118
|
+
column = [column_name.delete(':').delete(' ')] # Set the header of the data to the variable name, removing : and spaces
|
119
|
+
|
120
|
+
if ts.empty?
|
121
|
+
log "No time series for #{variable_name}:#{key_value}... defaulting to #{default_if_empty}"
|
122
|
+
# needs to be data.size-1 since the column name is already stored above (+=)
|
123
|
+
column += [default_if_empty] * (data.size-1)
|
124
|
+
else
|
125
|
+
ts = ts.get if ts.respond_to?(:get)
|
126
|
+
ts = ts.first if ts.respond_to?(:first)
|
127
|
+
|
128
|
+
start = Time.now
|
129
|
+
# Iterating in OpenStudio can take up to 60 seconds with 10min data. The quick_proc takes 0.03 seconds.
|
130
|
+
# for i in 0..ts.values.size - 1
|
131
|
+
# log "... at #{i}" if i % 10000 == 0
|
132
|
+
# column << ts.values[i]
|
133
|
+
# end
|
134
|
+
|
135
|
+
quick_proc = ts.values.to_s.split(',')
|
136
|
+
|
137
|
+
# the first and last have some cleanup items because of the Vector method
|
138
|
+
quick_proc[0] = quick_proc[0].gsub(/^.*\(/, '')
|
139
|
+
quick_proc[-1] = quick_proc[-1].delete(')')
|
140
|
+
column += quick_proc
|
141
|
+
|
142
|
+
log "Took #{Time.now - start} to iterate"
|
143
|
+
end
|
144
|
+
|
145
|
+
log 'Appending column to data'
|
146
|
+
|
147
|
+
# append the data to the end of the rows
|
148
|
+
if column.size == data.size
|
149
|
+
data.each_index do |index|
|
150
|
+
data[index] << column[index]
|
151
|
+
end
|
152
|
+
end
|
153
|
+
|
154
|
+
log "Finished extracting #{variable_name}"
|
155
|
+
end
|
156
|
+
|
157
|
+
def create_new_variable_sum(data, new_var_name, include_str, options=nil)
|
158
|
+
var_info = {
|
159
|
+
name: new_var_name,
|
160
|
+
var_indexes: []
|
161
|
+
}
|
162
|
+
data.each_with_index do |row, index|
|
163
|
+
if index.zero?
|
164
|
+
# Get the index of the columns to add
|
165
|
+
row.each do |c|
|
166
|
+
if c.include? include_str
|
167
|
+
var_info[:var_indexes] << row.index(c)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
# add the new var to the header row
|
172
|
+
data[0] << var_info[:name]
|
173
|
+
else
|
174
|
+
# sum the values
|
175
|
+
sum = 0
|
176
|
+
var_info[:var_indexes].each do |var|
|
177
|
+
temp_v = row[var].to_f
|
178
|
+
if options.nil?
|
179
|
+
sum += temp_v
|
180
|
+
elsif options[:positive_only] && temp_v > 0
|
181
|
+
sum += temp_v
|
182
|
+
elsif options[:negative_only] && temp_v < 0
|
183
|
+
sum += temp_v
|
184
|
+
end
|
185
|
+
end
|
186
|
+
|
187
|
+
# Also round the data here, because we don't need 10 decimals
|
188
|
+
data[index] << sum.round(1)
|
189
|
+
end
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def run(runner, user_arguments)
|
194
|
+
super(runner, user_arguments)
|
195
|
+
|
196
|
+
# get the last model and sql file
|
197
|
+
model = runner.lastOpenStudioModel
|
198
|
+
if model.empty?
|
199
|
+
runner.registerError('Cannot find last model.')
|
200
|
+
return false
|
201
|
+
end
|
202
|
+
model = model.get
|
203
|
+
|
204
|
+
# use the built-in error checking
|
205
|
+
return false unless runner.validateUserArguments(arguments(model), user_arguments)
|
206
|
+
|
207
|
+
# get the last model and sql file
|
208
|
+
model = runner.lastOpenStudioModel
|
209
|
+
if model.empty?
|
210
|
+
runner.registerError('Cannot find last model.')
|
211
|
+
return false
|
212
|
+
end
|
213
|
+
model = model.get
|
214
|
+
|
215
|
+
sqlFile = runner.lastEnergyPlusSqlFile
|
216
|
+
if sqlFile.empty?
|
217
|
+
runner.registerError('Cannot find last sql file.')
|
218
|
+
return false
|
219
|
+
end
|
220
|
+
sqlFile = sqlFile.get
|
221
|
+
model.setSqlFile(sqlFile)
|
222
|
+
|
223
|
+
# create a new csv with the values and save to the reports directory.
|
224
|
+
# assumptions:
|
225
|
+
# - all the variables exist
|
226
|
+
# - data are the same length
|
227
|
+
|
228
|
+
# initialize the rows with the header
|
229
|
+
log 'Starting to process Timeseries data'
|
230
|
+
# Initial header row
|
231
|
+
rows = [
|
232
|
+
['Date Time', 'Month', 'Day', 'Day of Week', 'Hour', 'Minute', 'SecondsFromStart']
|
233
|
+
]
|
234
|
+
|
235
|
+
# just grab one of the variables to get the date/time stamps
|
236
|
+
# ts = sqlFile.timeSeries('RUN PERIOD 1', 'Zone Timestep', 'Cooling:Electricity')
|
237
|
+
ts = sqlFile.timeSeries('RUN PERIOD 1', 'Hourly', 'Cooling:Electricity')
|
238
|
+
unless ts.empty?
|
239
|
+
ts = ts.first
|
240
|
+
dt_base = nil
|
241
|
+
# Save off the date time values
|
242
|
+
ts.dateTimes.each_with_index do |dt, index|
|
243
|
+
runner.registerInfo("My index is #{index}")
|
244
|
+
dt_base = DateTime.parse(dt.to_s) if dt_base.nil?
|
245
|
+
dt_current = DateTime.parse(dt.to_s)
|
246
|
+
rows << [
|
247
|
+
DateTime.parse(dt.to_s).strftime('%m/%d/%Y %H:%M'),
|
248
|
+
dt.date.monthOfYear.value,
|
249
|
+
dt.date.dayOfMonth,
|
250
|
+
dt.date.dayOfWeek.value,
|
251
|
+
dt.time.hours,
|
252
|
+
dt.time.minutes,
|
253
|
+
dt_current.to_time.to_i - dt_base.to_time.to_i
|
254
|
+
]
|
255
|
+
end
|
256
|
+
end
|
257
|
+
|
258
|
+
# add in the other variables by columns -- should really pull this from the report variables defined above
|
259
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Site Outdoor Air Drybulb Temperature', 'Environment', 0)
|
260
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Site Outdoor Air Relative Humidity', 'Environment', 0)
|
261
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Heating:Electricity', nil, 0)
|
262
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Heating:Gas', nil, 0)
|
263
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Cooling:Electricity', nil, 0)
|
264
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Electricity:Facility', nil, 0)
|
265
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Gas:Facility', nil, 0)
|
266
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Heating:EnergyTransfer', nil, 0)
|
267
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'WaterSystems:EnergyTransfer', nil, 0)
|
268
|
+
|
269
|
+
# get all zones and save the names for later use in aggregation.
|
270
|
+
tz_names = []
|
271
|
+
model.getThermalZones.each do |tz|
|
272
|
+
tz_names << tz.name.get if tz.name.is_initialized
|
273
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Zone Predicted Sensible Load to Setpoint Heat Transfer Rate', tz_names.last, 0)
|
274
|
+
extract_timeseries_into_matrix(sqlFile, rows, 'Water Heater Heating Rate', tz_names.last, 0)
|
275
|
+
end
|
276
|
+
|
277
|
+
# sum up a couple of the columns and create a new columns
|
278
|
+
create_new_variable_sum(rows, 'TotalSensibleLoad', 'ZonePredictedSensibleLoadtoSetpointHeatTransferRate')
|
279
|
+
create_new_variable_sum(rows, 'TotalCoolingSensibleLoad', 'ZonePredictedSensibleLoadtoSetpointHeatTransferRate', negative_only: true)
|
280
|
+
create_new_variable_sum(rows, 'TotalHeatingSensibleLoad', 'ZonePredictedSensibleLoadtoSetpointHeatTransferRate', positive_only: true)
|
281
|
+
create_new_variable_sum(rows, 'TotalWaterHeating', 'WaterHeaterHeatingRate')
|
282
|
+
|
283
|
+
# convert this to CSV object
|
284
|
+
File.open('./building_loads.csv', 'w') do |f|
|
285
|
+
rows.each do |row|
|
286
|
+
f << row.join(',') << "\n"
|
287
|
+
end
|
288
|
+
end
|
289
|
+
|
290
|
+
# covert the row data into the format needed by modelica
|
291
|
+
modelica_data = [['seconds', 'cooling', 'heating', 'waterheating']]
|
292
|
+
seconds_index = nil
|
293
|
+
total_water_heating_index = nil
|
294
|
+
total_cooling_sensible_index = nil
|
295
|
+
total_heating_sensible_index = nil
|
296
|
+
peak_cooling = 0
|
297
|
+
peak_heating = 0
|
298
|
+
peak_water_heating = 0
|
299
|
+
rows.each_with_index do |row, index|
|
300
|
+
if index.zero?
|
301
|
+
seconds_index = row.index('SecondsFromStart')
|
302
|
+
total_cooling_sensible_index = row.index('TotalCoolingSensibleLoad')
|
303
|
+
total_heating_sensible_index = row.index('TotalHeatingSensibleLoad')
|
304
|
+
total_water_heating_index = row.index('TotalWaterHeating')
|
305
|
+
else
|
306
|
+
new_data = [
|
307
|
+
row[seconds_index],
|
308
|
+
row[total_cooling_sensible_index],
|
309
|
+
row[total_heating_sensible_index],
|
310
|
+
row[total_water_heating_index]
|
311
|
+
]
|
312
|
+
|
313
|
+
modelica_data << new_data
|
314
|
+
|
315
|
+
# store the peaks
|
316
|
+
peak_cooling = row[total_cooling_sensible_index] if row[total_cooling_sensible_index] < peak_cooling
|
317
|
+
peak_heating = row[total_heating_sensible_index] if row[total_heating_sensible_index] > peak_heating
|
318
|
+
peak_water_heating = row[total_water_heating_index] if row[total_water_heating_index] > peak_water_heating
|
319
|
+
end
|
320
|
+
end
|
321
|
+
|
322
|
+
File.open('./modelica.mos', 'w') do |f|
|
323
|
+
f << "#1\n"
|
324
|
+
f << "#Heating and Cooling Model loads from OpenStudio Prototype Buildings\n"
|
325
|
+
f << "# Building Type: {{BUILDINGTYPE}}\n"
|
326
|
+
f << "# Climate Zone: {{CLIMATEZONE}}\n"
|
327
|
+
f << "# Vintage: {{VINTAGE}}\n"
|
328
|
+
f << "# Simulation ID (for debugging): {{SIMID}}\n"
|
329
|
+
f << "# URL: https://github.com/urbanopt/openstudio-prototype-loads\n"
|
330
|
+
f << "\n"
|
331
|
+
f << "#First column: Seconds in the year (loads are hourly)\n"
|
332
|
+
f << "#Second column: cooling loads in Watts (as negative numbers).\n"
|
333
|
+
f << "#Third column: space heating loads in Watts\n"
|
334
|
+
f << "#Fourth column: water heating in Watts\n"
|
335
|
+
f << "\n"
|
336
|
+
f << "#Peak space cooling load = #{peak_cooling} Watts\n"
|
337
|
+
f << "#Peak space heating load = #{peak_heating} Watts\n"
|
338
|
+
f << "#Peak water heating load = #{peak_water_heating} Watts\n"
|
339
|
+
f << "double tab1(8760,4)\n"
|
340
|
+
modelica_data.each_with_index do |row, index|
|
341
|
+
next if index.zero?
|
342
|
+
f << row.join(';') << "\n"
|
343
|
+
end
|
344
|
+
end
|
345
|
+
|
346
|
+
# Find the total runtime for energyplus and save it into a registerValue
|
347
|
+
total_time = -999
|
348
|
+
location_of_file = ['../eplusout.end', './run/eplusout.end']
|
349
|
+
first_index = location_of_file.map {|f| File.exist?(f)}.index(true)
|
350
|
+
if first_index
|
351
|
+
match = File.read(location_of_file[first_index]).to_s.match(/Elapsed.Time=(.*)hr(.*)min(.*)sec/)
|
352
|
+
total_time = match[1].to_i * 3600 + match[2].to_i * 60 + match[3].to_f
|
353
|
+
end
|
354
|
+
|
355
|
+
runner.registerValue('energyplus_runtime', total_time, 'sec')
|
356
|
+
runner.registerValue('peak_cooling_load', peak_cooling, 'W')
|
357
|
+
runner.registerValue('peak_heating_load', peak_heating, 'W')
|
358
|
+
runner.registerValue('peak_water_heating', peak_water_heating, 'W')
|
359
|
+
|
360
|
+
return true
|
361
|
+
ensure
|
362
|
+
sqlFile.close if sqlFile
|
363
|
+
end
|
364
|
+
end
|
365
|
+
|
366
|
+
# register the measure to be used by the application
|
367
|
+
ExportModelicaLoads.new.registerWithApplication
|