meeting 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (2) hide show
  1. data/lib/meeting/carbon_model.rb +155 -23
  2. metadata +26 -14
@@ -2,6 +2,23 @@
2
2
  # See LICENSE for details.
3
3
  # Contact Brighter Planet for dual-license arrangements.
4
4
 
5
+ ## Meeting carbon model
6
+ # This model is used by [Brighter Planet](http://brighterplanet.com)'s carbon emission [web service](http://carbon.brighterplanet.com) to estimate the **greenhouse gas emissions of a meeting** (e.g. a conference).
7
+ #
8
+ ##### Timeframe and date
9
+ # The model estimates the emissions that occur during a particular `timeframe`. To do this it needs to know the meeting's `date`. For example, if the `timeframe` is January 2010, a meeting that occurred on January 11 2010 will have emissions but a meeting that occurred on Febraury 1 2010 will not.
10
+ #
11
+ ##### Calculations
12
+ # The final estimate is the result of the **calculations** detailed below. These calculations are performed in reverse order, starting with the last calculation listed and finishing with the `emission` calculation. Each calculation is named according to the value it returns.
13
+ #
14
+ ##### Methods
15
+ # To accomodate varying client input, each calculation may have one or more **methods**. These are listed under each calculation in order from most to least preferred. Each method is named according to the values it requires. If any of these values is not available the method will be ignored. If all the methods for a calculation are ignored, the calculation will not return a value. "Default" methods do not require any values, and so a calculation with a default method will always return a value.
16
+ #
17
+ ##### Standard compliance
18
+ # Each method lists any established calculation standards with which it **complies**. When compliance with a standard is requested, all methods that do not comply with that standard are ignored. This means that any values a particular method requires will have been calculated using a compliant method, because those are the only methods available. If any value did not have a compliant method in its calculation then it would be undefined, and the current method would have been ignored.
19
+ #
20
+ ##### Collaboration
21
+ # Contributions to this carbon model are actively encouraged and warmly welcomed. This library includes a comprehensive test suite to ensure that your changes do not cause regressions. All changes should include test coverage for new functionality. Please see [sniff](http://github.com/brighterplanet/sniff#readme), our emitter testing framework, for more information.
5
22
  require 'conversions'
6
23
 
7
24
  module BrighterPlanet
@@ -9,33 +26,46 @@ module BrighterPlanet
9
26
  module CarbonModel
10
27
  def self.included(base)
11
28
  base.decide :emission, :with => :characteristics do
12
- committee :emission do # returns kg CO2e
29
+ ### Emission calculation
30
+ # Returns the `emission` estimate (*kg CO<sub>2</sub>e*).
31
+ # This is the total emission produced by the meeting venue.
32
+ committee :emission do
33
+ #### Emission from duration, area, and emission factor
34
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
35
+ #
36
+ # Multiplies `area` (*square m*) by `duration` (*hours*) and the `emission factor` (*kg CO<sub>2</sub>e / square m hour*) to give *kg CO<sub>2</sub>e*.
13
37
  quorum 'from duration, area, and emission factor', :needs => [:duration, :area, :emission_factor] do |characteristics|
14
38
  characteristics[:duration] * characteristics[:area] * characteristics[:emission_factor]
15
39
  end
16
40
 
41
+ #### Default emission
42
+ # **Complies:**
43
+ #
44
+ # Displays an error if the previous method fails.
17
45
  quorum 'default' do
18
46
  raise "The emission committee's default quorum should never be called"
19
47
  end
20
48
  end
21
49
 
22
- committee :emission_factor do # returns kg CO2e / square metre hour
50
+ ### Emission factor calculation
51
+ # Returns the `emission factor` (*lbs CO<sub>2</sub>e / square m hour).
52
+ committee :emission_factor do
53
+ #### Emission factor from fuel intensities and eGRID subregion
54
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
55
+ #
56
+ # - Looks up the [natural gas](http://data.brighterplanet.com/fuels) emission factor (*kg CO<sub>2</sub>e / cubic m*)
57
+ # - Looks up the [fuel oil](http://data.brighterplanet.com/fuels) emission factor (*kg CO<sub>2</sub>e / l*)
58
+ # - Looks up the [eGRID subregion](http://data.brighterplanet.com/egrid_subregions) electricity emission factor
59
+ # - Divides the natural gas emission factor (*kg CO<sub>2</sub>e / cubic m*) by the natural gas energy content (38,339,000 *J / cubic m*) to give an energy-based natural gas emission factor (*kg CO<sub>2</sub>e / J*)
60
+ # - Divides the fuel oil emission factor (*kg CO<sub>2</sub>e / l*) by the fuel oil energy content (38,655,000 *J / l*) to give an energy-based fuel oil emission factor (*kg CO<sub>2</sub>e / J*)
61
+ # - Divides the energy-based natural gas emission factor by 0.817 and the energy-based fuel oil emission factor by 0.846, adds these together and divides by 2, and divides by 0.95. This gives a district heat emission factor (*kg CO<sub>2</sub>e / J*) based on the assumption that district heat is produced by 50% natural gas and 50% fuel oil, natural gas boilers are 81.7% efficient, fuel oil boilers are 84.6% efficient, and transmission losses are 5%.
62
+ # - Multiplies `natural gas intensity` by the natural gas emission factor, `fuel oil intensity` by the fuel oil emission factor, `electricity intensity` by the electricity emission factor, and `district heat intensity` by the district heat emission factor
63
+ # - Adds these together
23
64
  quorum 'from eGRID subregion and fuel intensities', :needs => [:egrid_subregion, :natural_gas_intensity, :fuel_oil_intensity, :electricity_intensity, :district_heat_intensity] do |characteristics|
24
65
  natural_gas = FuelType.find_by_name "Commercial Natural Gas"
25
66
  fuel_oil = FuelType.find_by_name "Distillate Fuel Oil 2"
26
-
27
- # FIXME TODO won't need this once we convert emission factors to co2 / unit energy
28
- # kg / J kg / cubic m J / cubic m
29
67
  natural_gas_energy_ef = natural_gas.emission_factor / 38_339_000
30
-
31
- # FIXME TODO won't need this once we convert emission factors to co2 / unit energy
32
- # kg / J kg / l J / l
33
68
  fuel_oil_energy_ef = fuel_oil.emission_factor / 38_655_000
34
-
35
- # based on CA-CP calculator
36
- # assume district heat is 50% natural gas 50% distillate fuel
37
- # assume natural gas boilers 81.7% efficient; fuel oil boilers 84.6% efficient
38
- # assume 5% transmission loss
39
69
  district_heat_emission_factor = (((natural_gas_energy_ef / 0.817) / 2) + ((fuel_oil_energy_ef / 0.846) / 2)) / 0.95
40
70
 
41
71
  (characteristics[:natural_gas_intensity] * natural_gas.emission_factor) +
@@ -45,83 +75,185 @@ module BrighterPlanet
45
75
  end
46
76
  end
47
77
 
78
+ ### Natural gas intensity calculation
79
+ # Returns the meeting venue's `natural gas intensity` (*cubic m / square m hour*).
48
80
  committee :natural_gas_intensity do # returns cubic metres per square metre hour
81
+ #### From census division
82
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
83
+ #
84
+ # Looks up the [census division](http://data.brighterplanet.com/census_divisions) meeting building `natural gas intensity` (*cubic m / square m hour*).
49
85
  quorum 'from census division', :needs => :census_division do |characteristics|
50
86
  characteristics[:census_division].meeting_building_natural_gas_intensity
51
87
  end
52
88
 
89
+ #### Default natural gas intensity
90
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
91
+ #
92
+ # Uses the U.S. average `natural gas intensity` (*cubic m / square m hour*).
53
93
  quorum 'default' do
54
94
  CensusDivision.fallback.meeting_building_natural_gas_intensity
55
95
  end
56
96
  end
57
97
 
58
- committee :fuel_oil_intensity do # returns litres per square metre hour
98
+ ### Fuel oil intensity calculation
99
+ # Returns the meeting venue's `fuel oil intensity` (*l / square m hour*).
100
+ committee :fuel_oil_intensity do
101
+ #### Fuel oil intensity from census division
102
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
103
+ #
104
+ # Looks up the [census division](http://data.brighterplanet.com/census_divisions) meeting building `fuel oil intensity` (*l / square m hour*).
59
105
  quorum 'from census division', :needs => :census_division do |characteristics|
60
106
  characteristics[:census_division].meeting_building_fuel_oil_intensity
61
107
  end
62
108
 
109
+ #### Default fuel oil intensity
110
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
111
+ #
112
+ # Uses the U.S. average `fuel oil intensity` (*l / square m hour*).
63
113
  quorum 'default' do
64
114
  CensusDivision.fallback.meeting_building_fuel_oil_intensity
65
115
  end
66
116
  end
67
117
 
68
- committee :electricity_intensity do # returns kilowatt hours per square metre hour
118
+ ### Electricity intensity calculation
119
+ # Returns the meeting venue's `electricity intensity` (*kWh / square m hour*).
120
+ committee :electricity_intensity do
121
+ #### Electricity intensity from census division and eGRID region
122
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
123
+ #
124
+ # - Looks up the [census division](http://data.brighterplanet.com/census_divisions) meeting building `electricity intensity` (*kWh / square m hour*)
125
+ # - Looks up the [eGRID region](http://data.brighterplanet.com/egrid_regions) loss factor
126
+ # - Divides the `electricity intensity` by 1 - the loss factor to account for electricity transmission and distribution losses
69
127
  quorum 'from eGRID region and census division', :needs => [:egrid_region, :census_division] do |characteristics|
70
128
  characteristics[:census_division].meeting_building_electricity_intensity / (1 - characteristics[:egrid_region].loss_factor)
71
129
  end
72
130
 
131
+ #### Electricity intensity from eGRID region
132
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
133
+ #
134
+ # - Uses the U.S. average meeting building `electricity intensity` (*kWh / square m hour*)
135
+ # - Looks up the [eGRID region](http://data.brighterplanet.com/egrid_regions) loss factor
136
+ # - Divides the `electricity intensity` by (1 - the loss factor) to account for electricity transmission and distribution losses
73
137
  quorum 'from eGRID region', :needs => :egrid_region do |characteristics|
74
138
  CensusDivision.fallback.meeting_building_electricity_intensity / (1 - characteristics[:egrid_region].loss_factor)
75
139
  end
76
140
  end
77
141
 
78
- committee :district_heat_intensity do # returns joules per square metre hour
142
+ ### District heat intensity calculation
143
+ # Returns the meeting venue's `district heat intensity` (*J / square m hour*)
144
+ committee :district_heat_intensity do
145
+ #### District heat intensity from census division
146
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
147
+ #
148
+ # Looks up the [census division](http://data.brighterplanet.com/census_divisions) meeting building `district heat intensity`.
79
149
  quorum 'from census division', :needs => :census_division do |characteristics|
80
150
  characteristics[:census_division].meeting_building_district_heat_intensity
81
151
  end
82
152
 
153
+ #### Default district heat intensity
154
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
155
+ #
156
+ # Uses the U.S. average.
83
157
  quorum 'default' do
84
158
  CensusDivision.fallback.meeting_building_district_heat_intensity
85
159
  end
86
160
  end
87
161
 
88
- committee :egrid_region do # returns eGRID region
162
+ ### eGRID region calculation
163
+ # Returns the meeting venue's [eGRID region](http://data.brighterplanet.com/egrid_regions).
164
+ committee :egrid_region do
165
+ #### eGRID region from eGRID subregion
166
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
167
+ #
168
+ # Looks up the [eGRID subregion](http://data.brighterplanet.com/egrid_subregions) `eGRID region`.
89
169
  quorum 'from eGRID subregion', :needs => :egrid_subregion do |characteristics|
90
170
  characteristics[:egrid_subregion].egrid_region
91
171
  end
92
172
  end
93
173
 
94
- committee :egrid_subregion do # returns eGRID subregion
174
+ ### eGRID subregion calculation
175
+ # Returns the meeting venue's [eGRID subregion](http://data.brighterplanet.com/egrid_subregions).
176
+ committee :egrid_subregion do
177
+ #### eGRID subregion from zip code
178
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
179
+ #
180
+ # Looks up the [zip code](http://data.brighterplanet.com/zip_codes) `eGRID subregion`.
95
181
  quorum 'from zip code', :needs => :zip_code do |characteristics|
96
182
  characteristics[:zip_code].egrid_subregion
97
183
  end
98
184
 
185
+ #### Default eGRID subregion
186
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
187
+ #
188
+ # Uses an artificial eGRID subregion that represents the U.S. average.
99
189
  quorum 'default' do
100
190
  EgridSubregion.find_by_abbreviation 'US'
101
191
  end
102
192
  end
103
193
 
104
- committee :census_division do # returns census division
194
+ ### Census division calculation
195
+ # Returns the meeting venue's [census division](http://data.brighterplanet.com/census_divisions).
196
+ committee :census_division do
197
+ #### Census division from state
198
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
199
+ #
200
+ # Looks up the [state](http://data.brighterplanet.com/states) `census division`.
105
201
  quorum 'from state', :needs => :state do |characteristics|
106
202
  characteristics[:state].census_division
107
203
  end
108
204
  end
109
205
 
110
- committee :state do # returns state
206
+ ### State calculation
207
+ # Returns the meeting venue's [state](http://data.brighterplanet.com/states).
208
+ committee :state do
209
+ #### State from zip code
210
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
211
+ #
212
+ # Looks up the [zip code](http://data.brighterplanet.com/zip_codes) `state`.
111
213
  quorum 'from zip code', :needs => :zip_code do |characteristics|
112
214
  characteristics[:zip_code].state
113
215
  end
114
216
  end
115
217
 
116
- committee :area do # returns square meters
218
+ ### Zip code calculation
219
+ # Returns the meeting venue's [zip code](http://data.brighterplanet.com/zip_codes).
220
+ #### Zip code from client input
221
+ # **Complies:** All
222
+ #
223
+ # Uses the client-input [zip code](http://data.brighterplanet.com/zip_codes).
224
+
225
+ ### Area calculation
226
+ # Returns the meeting venue's `area` (*square m*).
227
+ committee :area do
228
+ #### Area from client input
229
+ # **Complies:** All
230
+ #
231
+ # Uses the client-input `area` (*square m*).
232
+
233
+ #### Default area
234
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
235
+ #
236
+ # Uses a default `area` of 1,184.5 *square m*.
237
+ # This is the median size of buildings in the [EIA Commercial Building Energy Consumption Survey](http://www.eia.doe.gov/emeu/cbecs/).
117
238
  quorum 'default' do
118
239
  base.fallback.area
119
240
  end
120
241
  end
121
242
 
122
- committee :duration do # returns hours
243
+ ### Duration calculation
244
+ # Returns the meeting's `duration` (hours).
245
+ committee :duration do
246
+ #### Duration from client input
247
+ # **Complies:** All
248
+ #
249
+ # Uses the client-input `duration` (*hours*).
250
+
251
+ #### Default duration
252
+ # **Complies:** GHG Protocol, ISO 14064-1, Climate Registry Protocol
253
+ #
254
+ # Uses a default `duration` of 8 *hours*.
123
255
  quorum 'default' do
124
- base.fallback.duration
256
+ 8
125
257
  end
126
258
  end
127
259
  end
metadata CHANGED
@@ -1,12 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: meeting
3
3
  version: !ruby/object:Gem::Version
4
+ hash: 15
4
5
  prerelease: false
5
6
  segments:
6
7
  - 0
7
8
  - 0
8
- - 7
9
- version: 0.0.7
9
+ - 8
10
+ version: 0.0.8
10
11
  platform: ruby
11
12
  authors:
12
13
  - Andy Rossmeissl
@@ -18,102 +19,110 @@ autorequire:
18
19
  bindir: bin
19
20
  cert_chain: []
20
21
 
21
- date: 2010-10-19 00:00:00 -04:00
22
+ date: 2010-11-17 00:00:00 -08:00
22
23
  default_executable:
23
24
  dependencies:
24
25
  - !ruby/object:Gem::Dependency
25
26
  name: activerecord
27
+ prerelease: false
26
28
  requirement: &id001 !ruby/object:Gem::Requirement
27
29
  none: false
28
30
  requirements:
29
31
  - - ~>
30
32
  - !ruby/object:Gem::Version
33
+ hash: 7
31
34
  segments:
32
35
  - 3
33
36
  - 0
34
37
  - 0
35
38
  version: 3.0.0
36
39
  type: :development
37
- prerelease: false
38
40
  version_requirements: *id001
39
41
  - !ruby/object:Gem::Dependency
40
42
  name: bundler
43
+ prerelease: false
41
44
  requirement: &id002 !ruby/object:Gem::Requirement
42
45
  none: false
43
46
  requirements:
44
47
  - - ~>
45
48
  - !ruby/object:Gem::Version
49
+ hash: 23
46
50
  segments:
47
51
  - 1
48
52
  - 0
49
53
  - 0
50
54
  version: 1.0.0
51
55
  type: :development
52
- prerelease: false
53
56
  version_requirements: *id002
54
57
  - !ruby/object:Gem::Dependency
55
58
  name: cucumber
59
+ prerelease: false
56
60
  requirement: &id003 !ruby/object:Gem::Requirement
57
61
  none: false
58
62
  requirements:
59
63
  - - ~>
60
64
  - !ruby/object:Gem::Version
65
+ hash: 57
61
66
  segments:
62
67
  - 0
63
68
  - 8
64
69
  - 3
65
70
  version: 0.8.3
66
71
  type: :development
67
- prerelease: false
68
72
  version_requirements: *id003
69
73
  - !ruby/object:Gem::Dependency
70
74
  name: jeweler
75
+ prerelease: false
71
76
  requirement: &id004 !ruby/object:Gem::Requirement
72
77
  none: false
73
78
  requirements:
74
79
  - - ~>
75
80
  - !ruby/object:Gem::Version
81
+ hash: 7
76
82
  segments:
77
83
  - 1
78
84
  - 4
79
85
  - 0
80
86
  version: 1.4.0
81
87
  type: :development
82
- prerelease: false
83
88
  version_requirements: *id004
84
89
  - !ruby/object:Gem::Dependency
85
90
  name: rake
91
+ prerelease: false
86
92
  requirement: &id005 !ruby/object:Gem::Requirement
87
93
  none: false
88
94
  requirements:
89
95
  - - ">="
90
96
  - !ruby/object:Gem::Version
97
+ hash: 3
91
98
  segments:
92
99
  - 0
93
100
  version: "0"
94
101
  type: :development
95
- prerelease: false
96
102
  version_requirements: *id005
97
103
  - !ruby/object:Gem::Dependency
98
104
  name: rdoc
105
+ prerelease: false
99
106
  requirement: &id006 !ruby/object:Gem::Requirement
100
107
  none: false
101
108
  requirements:
102
109
  - - ">="
103
110
  - !ruby/object:Gem::Version
111
+ hash: 3
104
112
  segments:
105
113
  - 0
106
114
  version: "0"
107
115
  type: :development
108
- prerelease: false
109
116
  version_requirements: *id006
110
117
  - !ruby/object:Gem::Dependency
111
118
  name: rspec
119
+ prerelease: false
112
120
  requirement: &id007 !ruby/object:Gem::Requirement
113
121
  none: false
114
122
  requirements:
115
123
  - - ~>
116
124
  - !ruby/object:Gem::Version
125
+ hash: 62196417
117
126
  segments:
118
127
  - 2
119
128
  - 0
@@ -122,52 +131,54 @@ dependencies:
122
131
  - 17
123
132
  version: 2.0.0.beta.17
124
133
  type: :development
125
- prerelease: false
126
134
  version_requirements: *id007
127
135
  - !ruby/object:Gem::Dependency
128
136
  name: sniff
137
+ prerelease: false
129
138
  requirement: &id008 !ruby/object:Gem::Requirement
130
139
  none: false
131
140
  requirements:
132
141
  - - ~>
133
142
  - !ruby/object:Gem::Version
143
+ hash: 23
134
144
  segments:
135
145
  - 0
136
146
  - 2
137
147
  - 0
138
148
  version: 0.2.0
139
149
  type: :development
140
- prerelease: false
141
150
  version_requirements: *id008
142
151
  - !ruby/object:Gem::Dependency
143
152
  name: emitter
153
+ prerelease: false
144
154
  requirement: &id009 !ruby/object:Gem::Requirement
145
155
  none: false
146
156
  requirements:
147
157
  - - ~>
148
158
  - !ruby/object:Gem::Version
159
+ hash: 21
149
160
  segments:
150
161
  - 0
151
162
  - 1
152
163
  - 7
153
164
  version: 0.1.7
154
165
  type: :runtime
155
- prerelease: false
156
166
  version_requirements: *id009
157
167
  - !ruby/object:Gem::Dependency
158
168
  name: earth
169
+ prerelease: false
159
170
  requirement: &id010 !ruby/object:Gem::Requirement
160
171
  none: false
161
172
  requirements:
162
173
  - - ~>
163
174
  - !ruby/object:Gem::Version
175
+ hash: 21
164
176
  segments:
165
177
  - 0
166
178
  - 2
167
179
  - 1
168
180
  version: 0.2.1
169
181
  type: :runtime
170
- prerelease: false
171
182
  version_requirements: *id010
172
183
  description: A software model in Ruby for the greenhouse gas emissions of a meeting
173
184
  email: andy@rossmeissl.net
@@ -206,7 +217,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
206
217
  requirements:
207
218
  - - ">="
208
219
  - !ruby/object:Gem::Version
209
- hash: 1523467767395695544
220
+ hash: 3
210
221
  segments:
211
222
  - 0
212
223
  version: "0"
@@ -215,6 +226,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
215
226
  requirements:
216
227
  - - ">="
217
228
  - !ruby/object:Gem::Version
229
+ hash: 3
218
230
  segments:
219
231
  - 0
220
232
  version: "0"