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.
Files changed (58) hide show
  1. checksums.yaml +4 -4
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +19 -0
  3. data/.github/ISSUE_TEMPLATE/feature_request.md +15 -0
  4. data/.github/pull_request_template.md +13 -0
  5. data/.rdoc_options +36 -0
  6. data/CHANGELOG.md +43 -1
  7. data/LICENSE.md +1 -1
  8. data/RDOC_MAIN.md +10 -0
  9. data/deploy_docs.sh +5 -0
  10. data/doc_templates/LICENSE.md +1 -1
  11. data/doc_templates/copyright_erb.txt +1 -1
  12. data/doc_templates/copyright_js.txt +1 -1
  13. data/doc_templates/copyright_ruby.txt +1 -1
  14. data/docs/.gitignore +3 -0
  15. data/docs/.vuepress/components/InnerJsonSchema.vue +76 -0
  16. data/docs/.vuepress/components/JsonSchema.vue +12 -0
  17. data/docs/.vuepress/components/ScenarioSchema.vue +12 -0
  18. data/docs/.vuepress/components/StaticLink.vue +8 -0
  19. data/docs/.vuepress/config.js +25 -0
  20. data/docs/.vuepress/highlight.js +8 -0
  21. data/docs/.vuepress/json-schema-deref-loader.js +22 -0
  22. data/docs/.vuepress/public/custom_rdoc_styles.css +78 -0
  23. data/docs/.vuepress/styles/palette.styl +1 -0
  24. data/docs/.vuepress/utils.js +17 -0
  25. data/docs/README.md +9 -0
  26. data/docs/package-lock.json +10018 -0
  27. data/docs/package.json +30 -0
  28. data/docs/schemas/scenario-schema.md +3 -0
  29. data/lib/measures/default_feature_reports/LICENSE.md +1 -1
  30. data/lib/measures/default_feature_reports/measure.rb +231 -87
  31. data/lib/measures/default_feature_reports/measure.xml +11 -11
  32. data/lib/measures/export_modelica_loads/LICENSE.md +27 -0
  33. data/lib/measures/export_modelica_loads/README.md +26 -0
  34. data/lib/measures/export_modelica_loads/README.md.erb +42 -0
  35. data/lib/measures/export_modelica_loads/docs/.gitkeep +0 -0
  36. data/lib/measures/export_modelica_loads/measure.rb +367 -0
  37. data/lib/measures/export_modelica_loads/measure.xml +92 -0
  38. data/lib/measures/export_modelica_loads/resources/report.html.in +13 -0
  39. data/lib/measures/export_time_series_modelica/LICENSE.md +1 -0
  40. data/lib/measures/export_time_series_modelica/README.md +59 -0
  41. data/lib/measures/export_time_series_modelica/README.md.erb +42 -0
  42. data/lib/measures/export_time_series_modelica/docs/.gitkeep +0 -0
  43. data/lib/measures/export_time_series_modelica/measure.rb +433 -0
  44. data/lib/measures/export_time_series_modelica/measure.xml +147 -0
  45. data/lib/measures/export_time_series_modelica/resources/os_lib_helper_methods.rb +399 -0
  46. data/lib/measures/export_time_series_modelica/resources/report.html.in +13 -0
  47. data/lib/urbanopt/reporting/default_reports/end_uses.rb +52 -38
  48. data/lib/urbanopt/reporting/default_reports/feature_report.rb +79 -8
  49. data/lib/urbanopt/reporting/default_reports/location.rb +11 -11
  50. data/lib/urbanopt/reporting/default_reports/program.rb +86 -86
  51. data/lib/urbanopt/reporting/default_reports/reporting_period.rb +98 -78
  52. data/lib/urbanopt/reporting/default_reports/scenario_report.rb +7 -4
  53. data/lib/urbanopt/reporting/default_reports/schema/scenario_csv_columns.txt +15 -0
  54. data/lib/urbanopt/reporting/default_reports/schema/scenario_schema.json +108 -80
  55. data/lib/urbanopt/reporting/default_reports/thermal_storage.rb +10 -10
  56. data/lib/urbanopt/reporting/version.rb +1 -1
  57. data/urbanopt-reporting-gem.gemspec +4 -4
  58. 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>1f4eb28d-d586-4c10-8d23-f3495054ce1e</version_id>
7
- <version_modified>20200921T204602Z</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>D8541540</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>A5706600</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>3C7B646E</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 %>
@@ -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