openstudio-common-measures 0.4.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.rubocop.yml +3 -1
  4. data/CHANGELOG.md +25 -0
  5. data/README.md +21 -2
  6. data/doc_templates/copyright_erb.txt +1 -1
  7. data/lib/measures/AddCostPerFloorAreaUnusedToLights/measure.xml +2 -8
  8. data/lib/measures/AddCostToSupplySideHVACComponentByAirLoop/measure.xml +9 -3
  9. data/lib/measures/AddSimplePvToShadingSurfacesByType/measure.xml +2 -2
  10. data/lib/measures/RemoveUnusedDefaultProfiles/measure.xml +2 -2
  11. data/lib/measures/ReportModelChanges/measure.xml +2 -2
  12. data/lib/measures/SetCOPforSingleSpeedDXCoolingUnits/measure.xml +4 -4
  13. data/lib/measures/SetCOPforTwoSpeedDXCoolingUnits/measure.xml +4 -4
  14. data/lib/measures/SetGasBurnerEfficiency/measure.xml +4 -4
  15. data/lib/measures/ShiftScheduleProfileTime/measure.xml +4 -4
  16. data/lib/measures/SwapLightsDefinition/measure.xml +3 -5
  17. data/lib/measures/add_ems_emissions_reporting/LICENSE.MD.txt +15 -0
  18. data/lib/measures/add_ems_emissions_reporting/LICENSE.md +27 -0
  19. data/lib/measures/add_ems_emissions_reporting/README.md +17 -0
  20. data/lib/measures/add_ems_emissions_reporting/measure.rb +474 -0
  21. data/lib/measures/add_ems_emissions_reporting/measure.xml +599 -0
  22. data/lib/measures/add_ems_emissions_reporting/resources/future_annual_co2e.csv +17 -0
  23. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2020.csv +8761 -0
  24. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2022.csv +8761 -0
  25. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2024.csv +8761 -0
  26. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2026.csv +8761 -0
  27. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2028.csv +8761 -0
  28. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2030.csv +8761 -0
  29. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2032.csv +8761 -0
  30. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2034.csv +8761 -0
  31. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2036.csv +8761 -0
  32. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2038.csv +8761 -0
  33. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2040.csv +8761 -0
  34. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2042.csv +8761 -0
  35. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2044.csv +8761 -0
  36. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2046.csv +8761 -0
  37. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2048.csv +8761 -0
  38. data/lib/measures/add_ems_emissions_reporting/resources/future_hourly_co2e_2050.csv +8761 -0
  39. data/lib/measures/add_ems_emissions_reporting/resources/historical_annual_co2e.csv +9 -0
  40. data/lib/measures/add_ems_emissions_reporting/resources/historical_hourly_co2e_2019.csv +8761 -0
  41. data/lib/measures/add_ev_load/measure.rb +51 -8
  42. data/lib/measures/add_ev_load/measure.xml +23 -5
  43. data/lib/measures/envelope_and_internal_load_breakdown/measure.xml +3 -3
  44. data/lib/measures/envelope_and_internal_load_breakdown/resources/report.html.erb +6 -1
  45. data/lib/measures/example_report/measure.xml +3 -3
  46. data/lib/measures/example_report/resources/report.html.erb +6 -1
  47. data/lib/measures/generic_qaqc/README.md +19 -4
  48. data/lib/measures/generic_qaqc/README.md.erb +7 -1
  49. data/lib/measures/generic_qaqc/docs/generic_qaqc_detailed.jpg +0 -0
  50. data/lib/measures/generic_qaqc/docs/generic_qaqc_summary.jpg +0 -0
  51. data/lib/measures/generic_qaqc/measure.rb +34 -29
  52. data/lib/measures/generic_qaqc/measure.xml +181 -82
  53. data/lib/measures/generic_qaqc/resources/check_cond_zns.rb +3 -1
  54. data/lib/measures/generic_qaqc/resources/check_domestic_hot_water.rb +13 -8
  55. data/lib/measures/generic_qaqc/resources/check_envelope_conductance.rb +330 -231
  56. data/lib/measures/generic_qaqc/resources/check_eui_by_end_use.rb +59 -20
  57. data/lib/measures/generic_qaqc/resources/check_eui_reasonableness.rb +58 -20
  58. data/lib/measures/generic_qaqc/resources/check_internal_loads.rb +57 -56
  59. data/lib/measures/generic_qaqc/resources/check_mech_sys_capacity.rb +4 -1
  60. data/lib/measures/generic_qaqc/resources/check_mech_sys_efficiency.rb +27 -22
  61. data/lib/measures/generic_qaqc/resources/check_mech_sys_part_load_eff.rb +4 -1
  62. data/lib/measures/generic_qaqc/resources/check_mech_sys_type.rb +3 -3
  63. data/lib/measures/generic_qaqc/resources/check_schedules.rb +65 -101
  64. data/lib/measures/generic_qaqc/resources/check_simultaneous_heating_and_cooling.rb +3 -1
  65. data/lib/measures/generic_qaqc/resources/check_supply_air_and_thermostat_temp_difference.rb +3 -1
  66. data/lib/measures/generic_qaqc/resources/os_lib_reporting_qaqc.rb +49 -15
  67. data/lib/measures/generic_qaqc/resources/report.html.erb +6 -1
  68. data/lib/measures/hvac_psychrometric_chart/measure.xml +4 -3
  69. data/lib/measures/hvac_psychrometric_chart/resources/report.html.erb +6 -1
  70. data/lib/measures/openstudio_results/measure.xml +3 -3
  71. data/lib/measures/openstudio_results/resources/report.html.erb +6 -1
  72. data/lib/measures/set_run_period/measure.xml +2 -2
  73. data/lib/measures/view_data/measure.xml +9 -9
  74. data/lib/measures/view_data/resources/report.html.in +1336 -973
  75. data/lib/measures/view_data/resources/va3c.rb +1 -0
  76. data/lib/measures/view_model/measure.xml +33 -64
  77. data/lib/measures/view_model/resources/report.html.in +1339 -976
  78. data/lib/measures/view_model/resources/va3c.rb +1 -0
  79. data/lib/openstudio/common_measures/version.rb +1 -1
  80. data/openstudio-common-measures.gemspec +2 -2
  81. metadata +33 -7
@@ -0,0 +1,474 @@
1
+ # *******************************************************************************
2
+ # OpenStudio(R), Copyright (c) 2008-2021, 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 'csv'
37
+ require 'openstudio-extension'
38
+ require 'openstudio/extension/core/os_lib_helper_methods'
39
+
40
+ # start the measure
41
+ class AddEMSEmissionsReporting < OpenStudio::Measure::ModelMeasure
42
+ # human readable name
43
+ def name
44
+ return 'Add EMS to Report Emissions'
45
+ end
46
+
47
+ # human readable description
48
+ def description
49
+ return 'This measure reports emissions based on user-provided future and historical years as well as future, historical hourly, and historical annual subregions.'
50
+ end
51
+
52
+ # human readable description of modeling approach
53
+ def modeler_description
54
+ return 'This measure uses the EnergyPlus Energy Management System to log and report emissions based on user-provided future and historical years as well as future, historical hourly, and historical annual subregions.'
55
+ end
56
+
57
+ # define the arguments that the user will input
58
+ def arguments(model)
59
+ args = OpenStudio::Measure::OSArgumentVector.new
60
+
61
+ # future subregion
62
+ future_subregion_chs = OpenStudio::StringVector.new
63
+ future_subregion_chs << 'AZNMc'
64
+ future_subregion_chs << 'CAMXc'
65
+ future_subregion_chs << 'ERCTc'
66
+ future_subregion_chs << 'FRCCc'
67
+ future_subregion_chs << 'MROEc'
68
+ future_subregion_chs << 'MROWc'
69
+ future_subregion_chs << 'NEWEc'
70
+ future_subregion_chs << 'NWPPc'
71
+ future_subregion_chs << 'NYSTc'
72
+ future_subregion_chs << 'RFCEc'
73
+ future_subregion_chs << 'RFCMc'
74
+ future_subregion_chs << 'RFCWc'
75
+ future_subregion_chs << 'RMPAc'
76
+ future_subregion_chs << 'SPNOc'
77
+ future_subregion_chs << 'SPSOc'
78
+ future_subregion_chs << 'SRMVc'
79
+ future_subregion_chs << 'SRMWc'
80
+ future_subregion_chs << 'SRSOc'
81
+ future_subregion_chs << 'SRTVc'
82
+ future_subregion_chs << 'SRVCc'
83
+
84
+ future_subregion = OpenStudio::Measure::OSArgument.makeChoiceArgument('future_subregion', future_subregion_chs, true)
85
+ future_subregion.setDisplayName('Future subregion')
86
+ future_subregion.setDescription('Future subregion. Options are: AZNMc, CAMXc, ERCTc, FRCCc, MROEc, MROWc, NEWEc, NWPPc, NYSTc, RFCEc, RFCMc, RFCWc, RMPAc, SPNOc, SPSOc, SRMVc, SRMWc, SRSOc, SRTVc, and SRVCc')
87
+ future_subregion.setDefaultValue('RMPAc')
88
+ args << future_subregion
89
+
90
+ # historical hourly subregion
91
+ hourly_historical_subregion_chs = OpenStudio::StringVector.new
92
+ hourly_historical_subregion_chs << 'California'
93
+ hourly_historical_subregion_chs << 'Carolinas'
94
+ hourly_historical_subregion_chs << 'Central'
95
+ hourly_historical_subregion_chs << 'Florida'
96
+ hourly_historical_subregion_chs << 'Mid-Atlantic'
97
+ hourly_historical_subregion_chs << 'Midwest'
98
+ hourly_historical_subregion_chs << 'New England'
99
+ hourly_historical_subregion_chs << 'New York'
100
+ hourly_historical_subregion_chs << 'Northwest'
101
+ hourly_historical_subregion_chs << 'Rocky Mountains'
102
+ hourly_historical_subregion_chs << 'Southeast'
103
+ hourly_historical_subregion_chs << 'Southwest'
104
+ hourly_historical_subregion_chs << 'Tennessee'
105
+ hourly_historical_subregion_chs << 'Texas'
106
+
107
+ hourly_historical_subregion = OpenStudio::Measure::OSArgument.makeChoiceArgument('hourly_historical_subregion', hourly_historical_subregion_chs, true)
108
+ hourly_historical_subregion.setDisplayName('Historical hourly subregion')
109
+ hourly_historical_subregion.setDescription('Historical hourly subregion. Options are: California, Carolinas, Central, Florida, Mid-Atlantic, Midwest, New England, New York, Northwest, Rocky Mountains, Southeast, Southwest, Tennessee, and Texas')
110
+ hourly_historical_subregion.setDefaultValue('Rocky Mountains')
111
+ args << hourly_historical_subregion
112
+
113
+ # historical annual subregion
114
+ annual_historical_subregion_chs = OpenStudio::StringVector.new
115
+ annual_historical_subregion_chs << 'AKGD'
116
+ annual_historical_subregion_chs << 'AKMS'
117
+ annual_historical_subregion_chs << 'AZNM'
118
+ annual_historical_subregion_chs << 'CAMX'
119
+ annual_historical_subregion_chs << 'ERCT'
120
+ annual_historical_subregion_chs << 'FRCC'
121
+ annual_historical_subregion_chs << 'HIMS'
122
+ annual_historical_subregion_chs << 'HIOA'
123
+ annual_historical_subregion_chs << 'MROE'
124
+ annual_historical_subregion_chs << 'MROW'
125
+ annual_historical_subregion_chs << 'NEWE'
126
+ annual_historical_subregion_chs << 'NWPP'
127
+ annual_historical_subregion_chs << 'NYCW'
128
+ annual_historical_subregion_chs << 'NYLI'
129
+ annual_historical_subregion_chs << 'NYUP'
130
+ annual_historical_subregion_chs << 'RFCE'
131
+ annual_historical_subregion_chs << 'RFCM'
132
+ annual_historical_subregion_chs << 'RFCW'
133
+ annual_historical_subregion_chs << 'RMPA'
134
+ annual_historical_subregion_chs << 'SPNO'
135
+ annual_historical_subregion_chs << 'SPSO'
136
+ annual_historical_subregion_chs << 'SRMV'
137
+ annual_historical_subregion_chs << 'SRMW'
138
+ annual_historical_subregion_chs << 'SRSO'
139
+ annual_historical_subregion_chs << 'SRTV'
140
+ annual_historical_subregion_chs << 'SRVC'
141
+
142
+ annual_historical_subregion = OpenStudio::Measure::OSArgument.makeChoiceArgument('annual_historical_subregion', annual_historical_subregion_chs, true)
143
+ annual_historical_subregion.setDisplayName('Historical annual subregion')
144
+ annual_historical_subregion.setDescription('Historical annual subregion. Options are: AKGD, AKMS, AZNM, CAMX, ERCT, FRCC, HIMS, HIOA, MROE, MROW, NEWE, NWPP, NYCW, NYLI, NYUP, RFCE, RFCM, RFCW, RMPA, SPNO, SPSO, SRMV, SRMW, SRSO, SRTV, and SRVC')
145
+ annual_historical_subregion.setDefaultValue('RMPA')
146
+ args << annual_historical_subregion
147
+
148
+ # future year
149
+ future_year_chs = OpenStudio::StringVector.new
150
+ future_year_chs << '2020'
151
+ future_year_chs << '2022'
152
+ future_year_chs << '2024'
153
+ future_year_chs << '2026'
154
+ future_year_chs << '2028'
155
+ future_year_chs << '2030'
156
+ future_year_chs << '2032'
157
+ future_year_chs << '2034'
158
+ future_year_chs << '2036'
159
+ future_year_chs << '2038'
160
+ future_year_chs << '2040'
161
+ future_year_chs << '2042'
162
+ future_year_chs << '2044'
163
+ future_year_chs << '2046'
164
+ future_year_chs << '2048'
165
+ future_year_chs << '2050'
166
+
167
+
168
+ future_year = OpenStudio::Measure::OSArgument.makeChoiceArgument('future_year', future_year_chs, true)
169
+ future_year.setDisplayName('Future Year')
170
+ future_year.setDescription('Future Year. Options are: 2020 to 2050 in two year increments')
171
+ future_year.setDefaultValue('2020')
172
+ args << future_year
173
+
174
+ # hourly historical year
175
+ hourly_historical_year_chs = OpenStudio::StringVector.new
176
+ hourly_historical_year_chs << '2019'
177
+
178
+ hourly_historical_year = OpenStudio::Measure::OSArgument.makeChoiceArgument('hourly_historical_year', hourly_historical_year_chs, true)
179
+ hourly_historical_year.setDisplayName('Hourly Historical Year')
180
+ hourly_historical_year.setDescription('Hourly Historical Year. Options are: 2019.')
181
+ hourly_historical_year.setDefaultValue('2019')
182
+ args << hourly_historical_year
183
+
184
+ # annual historical year
185
+ annual_historical_year_chs = OpenStudio::StringVector.new
186
+ annual_historical_year_chs << '2007'
187
+ annual_historical_year_chs << '2009'
188
+ annual_historical_year_chs << '2010'
189
+ annual_historical_year_chs << '2012'
190
+ annual_historical_year_chs << '2014'
191
+ annual_historical_year_chs << '2016'
192
+ annual_historical_year_chs << '2018'
193
+ annual_historical_year_chs << '2019'
194
+
195
+ annual_historical_year = OpenStudio::Measure::OSArgument.makeChoiceArgument('annual_historical_year', annual_historical_year_chs, true)
196
+
197
+ #puts "annual_historical_year = #{annual_historical_year}"
198
+
199
+ annual_historical_year.setDisplayName('Annual Historical Year')
200
+ annual_historical_year.setDescription('Annual Historical Year. Options are: 2007, 2009, 2010, 2012, 2014, 2016, 2018, and 2019.')
201
+ annual_historical_year.setDefaultValue('2019')
202
+ args << annual_historical_year
203
+
204
+ return args
205
+ end
206
+
207
+
208
+ # define what happens when the measure is run
209
+ def run(model, runner, usr_args)
210
+ super(model, runner, usr_args)
211
+
212
+ # use the built-in error checking
213
+ return false unless runner.validateUserArguments(arguments(model), usr_args)
214
+
215
+ # assign the user inputs to variables
216
+ future_subregion = runner.getStringArgumentValue('future_subregion', usr_args)
217
+ hourly_historical_subregion = runner.getStringArgumentValue('hourly_historical_subregion', usr_args)
218
+ annual_historical_subregion = runner.getStringArgumentValue('annual_historical_subregion', usr_args)
219
+ future_year = runner.getStringArgumentValue('future_year', usr_args).to_i
220
+ hourly_historical_year = runner.getStringArgumentValue('hourly_historical_year', usr_args).to_i
221
+ annual_historical_year = runner.getStringArgumentValue('annual_historical_year', usr_args).to_i
222
+
223
+ # log errors if users select arguments not supported by the measure
224
+ arguments(model).each do |argument|
225
+
226
+ case argument.name
227
+
228
+ when 'future_subregion'
229
+ if !argument.choiceValues.include? future_subregion
230
+ runner.registerError("#{future_subregion} is not a valid option. Please select from of the following future_subregion options #{argument.choiceValues}")
231
+ end
232
+ when 'hourly_historical_subregion'
233
+ if !argument.choiceValues.include? hourly_historical_subregion
234
+ runner.registerError("#{hourly_historical_subregion} is not a valid option. Please select from of the following hourly_historical_subregion options #{argument.choiceValues}")
235
+ end
236
+ when 'annual_historical_subregion'
237
+ if !argument.choiceValues.include? annual_historical_subregion
238
+ runner.registerError("#{annual_historical_subregion} is not a valid option. Please select from of the following annual_historical_subregion options #{argument.choiceValues}")
239
+ end
240
+ when 'future_year'
241
+ if !argument.choiceValues.include? future_year.to_s
242
+ runner.registerError("#{future_year} is not a valid option. Please select from of the following future_year options #{argument.choiceValues}")
243
+ end
244
+ when 'hourly_historical_year'
245
+ if !argument.choiceValues.include? hourly_historical_year.to_s
246
+ runner.registerError("#{hourly_historical_year} is not a valid option. Please select from of the following hourly_historical_year options #{argument.choiceValues}")
247
+ end
248
+ when 'annual_historical_year'
249
+ if !argument.choiceValues.include? annual_historical_year.to_s
250
+ runner.registerError("#{annual_historical_year} is not a valid option. Please select from of the following annual_historical_year options #{argument.choiceValues}")
251
+ end
252
+
253
+ end
254
+
255
+ end
256
+
257
+ fut_hr_path = "#{__dir__}/resources/future_hourly_co2e_#{future_year}.csv"
258
+ his_hr_path = "#{__dir__}/resources/historical_hourly_co2e_#{hourly_historical_year}.csv"
259
+ fut_yr_path = "#{__dir__}/resources/future_annual_co2e.csv"
260
+ his_yr_path = "#{__dir__}/resources/historical_annual_co2e.csv"
261
+
262
+ # find external files
263
+ if ((File.exist?(fut_hr_path)) and (File.exist?(fut_yr_path)) and (File.exist?(his_hr_path)) and (File.exist?(his_yr_path)))
264
+ fut_hr_file = OpenStudio::Model::ExternalFile.getExternalFile(model, fut_hr_path)
265
+ his_hr_file = OpenStudio::Model::ExternalFile.getExternalFile(model, his_hr_path)
266
+ fut_yr_file = OpenStudio::Model::ExternalFile.getExternalFile(model, fut_yr_path)
267
+ his_yr_file = OpenStudio::Model::ExternalFile.getExternalFile(model, his_yr_path)
268
+ if ((fut_hr_file.is_initialized) and (his_hr_file.is_initialized) and (fut_yr_file.is_initialized) and (his_yr_file.is_initialized))
269
+ fut_hr_file = fut_hr_file.get
270
+ his_hr_file = his_hr_file.get
271
+ fut_yr_file = fut_yr_file.get
272
+ his_yr_file = his_yr_file.get
273
+ fut_hr_data = CSV.read(fut_hr_path, headers: true)
274
+ his_hr_data = CSV.read(his_hr_path, headers: true)
275
+ fut_yr_data = CSV.read(fut_yr_path, headers: true)
276
+ his_yr_data = CSV.read(his_yr_path, headers: true)
277
+ end
278
+ else
279
+ runner.registerError("Could not find CSV file at one of more of the following paths: #{fut_hr_path}, #{his_hr_path}, #{fut_yr_path}, or #{his_yr_path}")
280
+ return false
281
+ end
282
+
283
+ # add schedule type limits for schedule file
284
+ lim_type = OpenStudio::Model::ScheduleTypeLimits.new(model)
285
+ lim_type.setName('Emissions Sch File Type Limits')
286
+
287
+ # add future schedule file
288
+ sch_file = OpenStudio::Model::ScheduleFile.new(fut_hr_file)
289
+ sch_file.setName("#{future_subregion} #{future_year} Future Hourly Emissions Sch")
290
+ sch_file.setScheduleTypeLimits(lim_type)
291
+ sch_file.setColumnNumber(fut_hr_data.headers.index(future_subregion) + 1)
292
+ sch_file.setRowstoSkipatTop(1)
293
+ sch_file.setNumberofHoursofData(8760)
294
+ sch_file.setColumnSeparator('Comma')
295
+ sch_file.setInterpolatetoTimestep(false)
296
+ sch_file.setMinutesperItem(60)
297
+
298
+ # add historical schedule file
299
+ sch_file = OpenStudio::Model::ScheduleFile.new(his_hr_file)
300
+ sch_file.setName("#{hourly_historical_subregion} #{hourly_historical_year} Historical Hourly Emissions Sch")
301
+ sch_file.setScheduleTypeLimits(lim_type)
302
+ sch_file.setColumnNumber(his_hr_data.headers.index(hourly_historical_subregion) + 1)
303
+ sch_file.setRowstoSkipatTop(1)
304
+ sch_file.setNumberofHoursofData(8760)
305
+ sch_file.setColumnSeparator('Comma')
306
+ sch_file.setInterpolatetoTimestep(false)
307
+ sch_file.setMinutesperItem(60)
308
+
309
+ # add EMS sensor for future schedule file
310
+ fut_sens = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
311
+ fut_sens.setKeyName("#{future_subregion} #{future_year} Future Hourly Emissions Sch")
312
+ fut_sens.setName('Fut_Sen')
313
+
314
+ # add EMS sensor for historical schedule file
315
+ his_sens = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Schedule Value')
316
+ his_sens.setKeyName("#{hourly_historical_subregion} #{hourly_historical_year} Historical Hourly Emissions Sch")
317
+ his_sens.setName('His_Sen')
318
+
319
+ # add whole-building electricity sensor
320
+ ele_sens = OpenStudio::Model::EnergyManagementSystemSensor.new(model, 'Facility Total Purchased Electricity Energy')
321
+ ele_sens.setKeyName('Whole Building')
322
+ ele_sens.setName('Ele_Sen')
323
+
324
+ ems_prgm = OpenStudio::Model::EnergyManagementSystemProgram.new(model)
325
+ ems_prgm.setName('Emissions_Calc_Prgm')
326
+ ems_prgm.addLine('SET fut_hr_val = Fut_Sen')
327
+ ems_prgm.addLine('SET his_hr_val = His_Sen')
328
+ fut_yr_data.each {|r| ems_prgm.addLine("SET fut_yr_val = #{r[future_subregion]}") if r[0].to_i == future_year}
329
+ his_yr_data.each {|r| ems_prgm.addLine("SET his_yr_val = #{r[annual_historical_subregion]}") if r[0].to_i == annual_historical_year}
330
+ ems_prgm.addLine('SET elec = Ele_Sen')
331
+ ems_prgm.addLine('SET conv = 1000000 * 60 * 60') # J to MWh (1000000J/MJ * 60hr/min * 60 min/sec)
332
+ ems_prgm.addLine('SET conv_kg_mt = 0.001') # kg to metric ton
333
+ ems_prgm.addLine('SET fut_hr = (fut_hr_val * elec / conv) * conv_kg_mt')
334
+ ems_prgm.addLine('SET his_hr = (his_hr_val * elec / conv) * conv_kg_mt')
335
+ ems_prgm.addLine('SET fut_yr = (fut_yr_val * elec / conv) * conv_kg_mt')
336
+ ems_prgm.addLine('SET his_yr = (his_yr_val * elec / conv) * conv_kg_mt')
337
+
338
+
339
+ #### add emissions intensity metric
340
+ # get building from model
341
+ building = model.getBuilding
342
+ floor_area = building.floorArea * 10.764 #change from m2 to ft2
343
+ #add metric
344
+ ems_prgm.addLine("SET fut_hr_intensity = fut_hr * 1000 / #{floor_area}") # unit: kg/ft2 - changed mt to kg
345
+ ems_prgm.addLine("SET his_hr_intensity = his_hr * 1000 / #{floor_area}") # unit: kg/ft2 - changed mt to kg
346
+ ems_prgm.addLine("SET fut_yr_intensity = fut_yr * 1000 / #{floor_area}") # unit: kg/ft2 - changed mt to kg
347
+ ems_prgm.addLine("SET his_yr_intensity = his_yr * 1000 / #{floor_area}") # unit: kg/ft2 - changed mt to kg
348
+
349
+ # add EMS program calling manager
350
+ mgr_prgm = OpenStudio::Model::EnergyManagementSystemProgramCallingManager.new(model)
351
+ mgr_prgm.setName('Emissions Calc Prgm')
352
+ mgr_prgm.setCallingPoint('EndOfSystemTimestepBeforeHVACReporting')
353
+ mgr_prgm.setProgram(ems_prgm, 0)
354
+
355
+ # add future hourly EMS output variable
356
+ ems_var1 = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, 'fut_hr')
357
+ ems_var1.setName('Future_Hourly_Electricity_Emissions')
358
+ ems_var1.setEMSVariableName('fut_hr')
359
+ ems_var1.setTypeOfDataInVariable('Summed')
360
+ ems_var1.setUpdateFrequency('SystemTimestep')
361
+ ems_var1.setEMSProgramOrSubroutineName(ems_prgm)
362
+ ems_var1.setUnits('mt')
363
+
364
+ # add historical hourly EMS output variable
365
+ ems_var2 = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, 'his_hr')
366
+ ems_var2.setName('Historical_Hourly_Electricity_Emissions')
367
+ ems_var2.setEMSVariableName('his_hr')
368
+ ems_var2.setTypeOfDataInVariable('Summed')
369
+ ems_var2.setUpdateFrequency('SystemTimestep')
370
+ ems_var2.setEMSProgramOrSubroutineName(ems_prgm)
371
+ ems_var2.setUnits('mt')
372
+
373
+ # add future annual EMS output variable
374
+ ems_var3 = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, 'fut_yr')
375
+ ems_var3.setName('Future_Annual_Electricity_Emissions')
376
+ ems_var3.setEMSVariableName('fut_yr')
377
+ ems_var3.setTypeOfDataInVariable('Summed')
378
+ ems_var3.setUpdateFrequency('SystemTimestep')
379
+ ems_var3.setEMSProgramOrSubroutineName(ems_prgm)
380
+ ems_var3.setUnits('mt')
381
+
382
+ # add historical annual EMS output variable
383
+ ems_var4 = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, 'his_yr')
384
+ ems_var4.setName('Historical_Annual_Electricity_Emissions')
385
+ ems_var4.setEMSVariableName('his_yr')
386
+ ems_var4.setTypeOfDataInVariable('Summed')
387
+ ems_var4.setUpdateFrequency('SystemTimestep')
388
+ ems_var4.setEMSProgramOrSubroutineName(ems_prgm)
389
+ ems_var4.setUnits('mt')
390
+
391
+
392
+ ##### add emissions intensity
393
+ # add future hourly EMS output variable
394
+ ems_var5 = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, 'fut_hr_intensity')
395
+ ems_var5.setName('Future_Hourly_Electricity_Emissions_Intensity')
396
+ ems_var5.setEMSVariableName('fut_hr_intensity')
397
+ ems_var5.setTypeOfDataInVariable('Summed')
398
+ ems_var5.setUpdateFrequency('SystemTimestep')
399
+ ems_var5.setEMSProgramOrSubroutineName(ems_prgm)
400
+ ems_var5.setUnits('kg/ft2')
401
+
402
+ # add historical hourly EMS output variable
403
+ ems_var6 = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, 'his_hr_intensity')
404
+ ems_var6.setName('Historical_Hourly_Electricity_Emissions_Intensity')
405
+ ems_var6.setEMSVariableName('his_hr_intensity')
406
+ ems_var6.setTypeOfDataInVariable('Summed')
407
+ ems_var6.setUpdateFrequency('SystemTimestep')
408
+ ems_var6.setEMSProgramOrSubroutineName(ems_prgm)
409
+ ems_var6.setUnits('kg/ft2')
410
+
411
+ # add future annual EMS output variable
412
+ ems_var7 = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, 'fut_yr_intensity')
413
+ ems_var7.setName('Future_Annual_Electricity_Emissions_Intensity')
414
+ ems_var7.setEMSVariableName('fut_yr_intensity')
415
+ ems_var7.setTypeOfDataInVariable('Summed')
416
+ ems_var7.setUpdateFrequency('SystemTimestep')
417
+ ems_var7.setEMSProgramOrSubroutineName(ems_prgm)
418
+ ems_var7.setUnits('kg/ft2')
419
+
420
+ # add historical annual EMS output variable
421
+ ems_var8 = OpenStudio::Model::EnergyManagementSystemOutputVariable.new(model, 'his_yr_intensity')
422
+ ems_var8.setName('Historical_Annual_Electricity_Emissions_Intensity')
423
+ ems_var8.setEMSVariableName('his_yr_intensity')
424
+ ems_var8.setTypeOfDataInVariable('Summed')
425
+ ems_var8.setUpdateFrequency('SystemTimestep')
426
+ ems_var8.setEMSProgramOrSubroutineName(ems_prgm)
427
+ ems_var8.setUnits('kg/ft2')
428
+
429
+ # add future hourly reporting output variable
430
+ out_var1 = OpenStudio::Model::OutputVariable.new('Future_Hourly_Electricity_Emissions', model)
431
+ out_var1.setKeyValue('EMS')
432
+ out_var1.setReportingFrequency('hourly')
433
+
434
+ # add historical hourly reporting output variable
435
+ out_var2 = OpenStudio::Model::OutputVariable.new('Historical_Hourly_Electricity_Emissions', model)
436
+ out_var2.setKeyValue('EMS')
437
+ out_var2.setReportingFrequency('hourly')
438
+
439
+ # add future annual reporting output variable
440
+ out_var3 = OpenStudio::Model::OutputVariable.new('Future_Annual_Electricity_Emissions', model)
441
+ out_var3.setKeyValue('EMS')
442
+ out_var3.setReportingFrequency('hourly')
443
+
444
+ # add historical annual reporting output variable
445
+ out_var4 = OpenStudio::Model::OutputVariable.new('Historical_Annual_Electricity_Emissions', model)
446
+ out_var4.setKeyValue('EMS')
447
+ out_var4.setReportingFrequency('hourly')
448
+
449
+ # add future hourly intensity reporting output variable
450
+ out_var5 = OpenStudio::Model::OutputVariable.new('Future_Hourly_Electricity_Emissions_Intensity', model)
451
+ out_var5.setKeyValue('EMS')
452
+ out_var5.setReportingFrequency('hourly')
453
+
454
+ # add historical hourly intensity reporting output variable
455
+ out_var6 = OpenStudio::Model::OutputVariable.new('Historical_Hourly_Electricity_Emissions_Intensity', model)
456
+ out_var6.setKeyValue('EMS')
457
+ out_var6.setReportingFrequency('hourly')
458
+
459
+ # add future annual intensity reporting output variable
460
+ out_var7 = OpenStudio::Model::OutputVariable.new('Future_Annual_Electricity_Emissions_Intensity', model)
461
+ out_var7.setKeyValue('EMS')
462
+ out_var7.setReportingFrequency('hourly')
463
+
464
+ # add historical annual intensity reporting output variable
465
+ out_var8 = OpenStudio::Model::OutputVariable.new('Historical_Annual_Electricity_Emissions_Intensity', model)
466
+ out_var8.setKeyValue('EMS')
467
+ out_var8.setReportingFrequency('hourly')
468
+
469
+ return true
470
+ end
471
+ end
472
+
473
+ # register the measure to be used by the application
474
+ AddEMSEmissionsReporting.new.registerWithApplication