meeting 0.0.1 → 0.0.3
Sign up to get free protection for your applications and to get access to all the features.
- data/features/meeting_committees.feature +98 -5
- data/features/meeting_emissions.feature +24 -2
- data/features/support/env.rb +1 -1
- data/lib/meeting/carbon_model.rb +93 -2
- data/lib/meeting/characterization.rb +4 -1
- data/lib/meeting/data.rb +5 -2
- data/lib/test_support/db/schema.rb +4 -1
- data/lib/test_support/meeting_record.rb +6 -0
- metadata +43 -43
@@ -1,8 +1,101 @@
|
|
1
1
|
Feature: Meeting Committee Calculations
|
2
2
|
The meeting model should generate correct committee calculations
|
3
3
|
|
4
|
-
Scenario:
|
5
|
-
Given
|
6
|
-
When the "
|
7
|
-
Then the committee should have used quorum "
|
8
|
-
And the conclusion of the committee should be "
|
4
|
+
Scenario: Duration committee from default
|
5
|
+
Given a meeting emitter
|
6
|
+
When the "duration" committee is calculated
|
7
|
+
Then the committee should have used quorum "default"
|
8
|
+
And the conclusion of the committee should be "8"
|
9
|
+
|
10
|
+
Scenario: Area committee from default
|
11
|
+
Given a meeting emitter
|
12
|
+
When the "area" committee is calculated
|
13
|
+
Then the committee should have used quorum "default"
|
14
|
+
And the conclusion of the committee should be "1184.51376"
|
15
|
+
|
16
|
+
Scenario: State committee from zip code
|
17
|
+
Given a meeting emitter
|
18
|
+
And a characteristic "zip_code.name" of "94122"
|
19
|
+
When the "state" committee is calculated
|
20
|
+
Then the committee should have used quorum "from zip code"
|
21
|
+
And the conclusion of the committee should have "postal_abbreviation" of "CA"
|
22
|
+
|
23
|
+
Scenario: Census division committee from state
|
24
|
+
Given a meeting emitter
|
25
|
+
And a characteristic "state.postal_abbreviation" of "CA"
|
26
|
+
When the "census_division" committee is calculated
|
27
|
+
Then the committee should have used quorum "from state"
|
28
|
+
And the conclusion of the committee should have "number" of "9"
|
29
|
+
|
30
|
+
Scenario: District heat intensity committee from default
|
31
|
+
Given a meeting emitter
|
32
|
+
When the "district_heat_intensity" committee is calculated
|
33
|
+
Then the committee should have used quorum "default"
|
34
|
+
And the conclusion of the committee should be "3458.7"
|
35
|
+
|
36
|
+
Scenario: District heat intensity committee from census division
|
37
|
+
Given a meeting emitter
|
38
|
+
And a characteristic "census_division.number" of "9"
|
39
|
+
When the "district_heat_intensity" committee is calculated
|
40
|
+
Then the committee should have used quorum "from census division"
|
41
|
+
And the conclusion of the committee should be "1000"
|
42
|
+
|
43
|
+
Scenario: Electricity intensity committee from default
|
44
|
+
Given a meeting emitter
|
45
|
+
When the "electricity_intensity" committee is calculated
|
46
|
+
Then the committee should have used quorum "default"
|
47
|
+
And the conclusion of the committee should be "0.072444"
|
48
|
+
|
49
|
+
Scenario: Electricity intensity committee from census division
|
50
|
+
Given a meeting emitter
|
51
|
+
And a characteristic "census_division.number" of "9"
|
52
|
+
When the "electricity_intensity" committee is calculated
|
53
|
+
Then the committee should have used quorum "from census division"
|
54
|
+
And the conclusion of the committee should be "3"
|
55
|
+
|
56
|
+
Scenario: Fuel oil intensity committee from default
|
57
|
+
Given a meeting emitter
|
58
|
+
When the "fuel_oil_intensity" committee is calculated
|
59
|
+
Then the committee should have used quorum "default"
|
60
|
+
And the conclusion of the committee should be "0.0037381"
|
61
|
+
|
62
|
+
Scenario: Fuel oil intensity committee from census division
|
63
|
+
Given a meeting emitter
|
64
|
+
And a characteristic "census_division.number" of "9"
|
65
|
+
When the "fuel_oil_intensity" committee is calculated
|
66
|
+
Then the committee should have used quorum "from census division"
|
67
|
+
And the conclusion of the committee should be "2"
|
68
|
+
|
69
|
+
Scenario: Natural gas intensity committee from default
|
70
|
+
Given a meeting emitter
|
71
|
+
When the "natural_gas_intensity" committee is calculated
|
72
|
+
Then the committee should have used quorum "default"
|
73
|
+
And the conclusion of the committee should be "0.011973"
|
74
|
+
|
75
|
+
Scenario: Natural gas intensity committee from census division
|
76
|
+
Given a meeting emitter
|
77
|
+
And a characteristic "census_division.number" of "9"
|
78
|
+
When the "natural_gas_intensity" committee is calculated
|
79
|
+
Then the committee should have used quorum "from census division"
|
80
|
+
And the conclusion of the committee should be "1"
|
81
|
+
|
82
|
+
Scenario: Emission factor committee from nothing
|
83
|
+
Given a meeting emitter
|
84
|
+
When the "natural_gas_intensity" committee is calculated
|
85
|
+
And the "fuel_oil_intensity" committee is calculated
|
86
|
+
And the "electricity_intensity" committee is calculated
|
87
|
+
And the "district_heat_intensity" committee is calculated
|
88
|
+
And the "emission_factor" committee is calculated
|
89
|
+
Then the committee should have used quorum "from fuel intensities"
|
90
|
+
And the conclusion of the committee should be "0.15470"
|
91
|
+
|
92
|
+
Scenario: Emission factor committee from census division
|
93
|
+
Given a meeting emitter
|
94
|
+
And a characteristic "census_division.number" of "9"
|
95
|
+
When the "natural_gas_intensity" committee is calculated
|
96
|
+
And the "fuel_oil_intensity" committee is calculated
|
97
|
+
And the "electricity_intensity" committee is calculated
|
98
|
+
And the "district_heat_intensity" committee is calculated
|
99
|
+
And the "emission_factor" committee is calculated
|
100
|
+
Then the committee should have used quorum "from fuel intensities"
|
101
|
+
And the conclusion of the committee should be "8.50002"
|
@@ -2,6 +2,28 @@ Feature: Meeting Emissions Calculations
|
|
2
2
|
The meeting model should generate correct emission calculations
|
3
3
|
|
4
4
|
Scenario: Calculations starting from nothing
|
5
|
-
Given
|
5
|
+
Given a meeting has nothing
|
6
6
|
When emissions are calculated
|
7
|
-
Then the emission value should be within "0.1" kgs of "
|
7
|
+
Then the emission value should be within "0.1" kgs of "1465.9"
|
8
|
+
|
9
|
+
Scenario: Calculations starting from duration
|
10
|
+
Given a meeting has "duration" of "1"
|
11
|
+
When emissions are calculated
|
12
|
+
Then the emission value should be within "0.1" kgs of "183.2"
|
13
|
+
|
14
|
+
Scenario: Calculations starting from area
|
15
|
+
Given a meeting has "area" of "1000"
|
16
|
+
When emissions are calculated
|
17
|
+
Then the emission value should be within "1" kgs of "1237.6"
|
18
|
+
|
19
|
+
Scenario: Calculations starting from zip code
|
20
|
+
Given a meeting has "zip_code.name" of "94122"
|
21
|
+
When emissions are calculated
|
22
|
+
Then the emission value should be within "1" kgs of "80547"
|
23
|
+
|
24
|
+
Scenario: Calculations starting from duration, area, and zip code
|
25
|
+
Given a meeting has "duration" of "1"
|
26
|
+
And it has "area" of "1000"
|
27
|
+
And it has "zip_code.name" of "94122"
|
28
|
+
When emissions are calculated
|
29
|
+
Then the emission value should be within "0.1" kgs of "8500.0"
|
data/features/support/env.rb
CHANGED
@@ -5,4 +5,4 @@ require 'cucumber'
|
|
5
5
|
require 'cucumber/formatter/unicode'
|
6
6
|
|
7
7
|
require 'sniff'
|
8
|
-
Sniff.init File.join(File.dirname(__FILE__), '..', '..'), :cucumber => true
|
8
|
+
Sniff.init File.join(File.dirname(__FILE__), '..', '..'), :cucumber => true, :earth => [:locality, :fuel, :residence]
|
data/lib/meeting/carbon_model.rb
CHANGED
@@ -8,14 +8,105 @@ module BrighterPlanet
|
|
8
8
|
base.extend ::Leap::Subject
|
9
9
|
base.decide :emission, :with => :characteristics do
|
10
10
|
committee :emission do # returns kg CO2e
|
11
|
-
quorum 'from
|
12
|
-
|
11
|
+
quorum 'from duration, area, and emission factor', :needs => [:duration, :area, :emission_factor] do |characteristics|
|
12
|
+
characteristics[:duration] * characteristics[:area] * characteristics[:emission_factor]
|
13
13
|
end
|
14
14
|
|
15
15
|
quorum 'default' do
|
16
16
|
raise "The emission committee's default quorum should never be called"
|
17
17
|
end
|
18
18
|
end
|
19
|
+
|
20
|
+
committee :emission_factor do # returns kg CO2e / square metre hour
|
21
|
+
quorum 'from fuel intensities', :needs => [:natural_gas_intensity, :fuel_oil_intensity, :electricity_intensity, :district_heat_intensity] do |characteristics|
|
22
|
+
natural_gas = FuelType.find_by_name "Commercial Natural Gas"
|
23
|
+
fuel_oil = FuelType.find_by_name "Distillate Fuel Oil 2"
|
24
|
+
electricity = ResidenceFuelType.find_by_name "electricity"
|
25
|
+
|
26
|
+
# FIXME TODO won't need this once we convert emission factors to co2 / unit energy
|
27
|
+
# kg / J kg / cubic m J / cubic m
|
28
|
+
natural_gas_energy_ef = natural_gas.emission_factor / 38_339_000
|
29
|
+
|
30
|
+
# FIXME TODO won't need this once we convert emission factors to co2 / unit energy
|
31
|
+
# kg / J kg / l J / l
|
32
|
+
fuel_oil_energy_ef = fuel_oil.emission_factor / 38_655_000
|
33
|
+
|
34
|
+
# based on CA-CP calculator
|
35
|
+
# assume district heat is 50% natural gas 50% distillate fuel
|
36
|
+
# assume natural gas boilers 81.7% efficient; fuel oil boilers 84.6% efficient
|
37
|
+
# assume 5% transmission loss
|
38
|
+
district_heat_emission_factor = (((natural_gas_energy_ef / 0.817) / 2) + ((fuel_oil_energy_ef / 0.846) / 2)) / 0.95
|
39
|
+
|
40
|
+
(characteristics[:natural_gas_intensity] * natural_gas.emission_factor) +
|
41
|
+
(characteristics[:fuel_oil_intensity] * fuel_oil.emission_factor) +
|
42
|
+
(characteristics[:electricity_intensity] * electricity.emission_factor) +
|
43
|
+
(characteristics[:district_heat_intensity] * district_heat_emission_factor)
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
committee :natural_gas_intensity do # returns cubic metres per square metre hour
|
48
|
+
quorum 'from census division', :needs => :census_division do |characteristics|
|
49
|
+
characteristics[:census_division].meeting_building_natural_gas_intensity
|
50
|
+
end
|
51
|
+
|
52
|
+
quorum 'default' do
|
53
|
+
CensusDivision.fallback.meeting_building_natural_gas_intensity
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
committee :fuel_oil_intensity do # returns litres per square metre hour
|
58
|
+
quorum 'from census division', :needs => :census_division do |characteristics|
|
59
|
+
characteristics[:census_division].meeting_building_fuel_oil_intensity
|
60
|
+
end
|
61
|
+
|
62
|
+
quorum 'default' do
|
63
|
+
CensusDivision.fallback.meeting_building_fuel_oil_intensity
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
committee :electricity_intensity do # returns kilowatt hours per square metre hour
|
68
|
+
quorum 'from census division', :needs => :census_division do |characteristics|
|
69
|
+
characteristics[:census_division].meeting_building_electricity_intensity
|
70
|
+
end
|
71
|
+
|
72
|
+
quorum 'default' do
|
73
|
+
CensusDivision.fallback.meeting_building_electricity_intensity
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
committee :district_heat_intensity do # returns joules per square metre hour
|
78
|
+
quorum 'from census division', :needs => :census_division do |characteristics|
|
79
|
+
characteristics[:census_division].meeting_building_district_heat_intensity
|
80
|
+
end
|
81
|
+
|
82
|
+
quorum 'default' do
|
83
|
+
CensusDivision.fallback.meeting_building_district_heat_intensity
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
committee :census_division do # returns census division
|
88
|
+
quorum 'from state', :needs => :state do |characteristics|
|
89
|
+
characteristics[:state].census_division
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
committee :state do # returns state
|
94
|
+
quorum 'from zip code', :needs => :zip_code do |characteristics|
|
95
|
+
characteristics[:zip_code].state
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
committee :area do # returns square meters
|
100
|
+
quorum 'default' do
|
101
|
+
base.fallback.area
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
committee :duration do # returns hours
|
106
|
+
quorum 'default' do
|
107
|
+
base.fallback.duration
|
108
|
+
end
|
109
|
+
end
|
19
110
|
end
|
20
111
|
end
|
21
112
|
end
|
@@ -6,7 +6,10 @@ module BrighterPlanet
|
|
6
6
|
def self.included(base)
|
7
7
|
base.send :include, Characterizable
|
8
8
|
base.characterize do
|
9
|
-
has :
|
9
|
+
has :area # square metres
|
10
|
+
has :duration # hours
|
11
|
+
has :zip_code
|
12
|
+
has :state
|
10
13
|
end
|
11
14
|
base.add_implicit_characteristics
|
12
15
|
end
|
data/lib/meeting/data.rb
CHANGED
@@ -6,9 +6,12 @@ module BrighterPlanet
|
|
6
6
|
def self.included(base)
|
7
7
|
base.data_miner do
|
8
8
|
schema do
|
9
|
-
float '
|
9
|
+
float 'area'
|
10
|
+
float 'duration'
|
11
|
+
string 'zip_code_name'
|
12
|
+
string 'state_postal_abbreviation'
|
10
13
|
end
|
11
|
-
|
14
|
+
|
12
15
|
process :run_data_miner_on_belongs_to_associations
|
13
16
|
end
|
14
17
|
end
|
@@ -6,4 +6,10 @@ require 'sniff'
|
|
6
6
|
class MeetingRecord < ActiveRecord::Base
|
7
7
|
include Sniff::Emitter
|
8
8
|
include BrighterPlanet::Meeting
|
9
|
+
|
10
|
+
belongs_to :zip_code, :foreign_key => 'zip_code_name'
|
11
|
+
belongs_to :state, :foreign_key => 'state_postal_abbreviation'
|
12
|
+
|
13
|
+
falls_back_on :area => 12_750.square_feet.to(:square_metres), # assume median-sized meeting building
|
14
|
+
:duration => 8 # assume 1 day
|
9
15
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: meeting
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 3
|
10
|
+
version: 0.0.3
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Andy Rossmeissl
|
@@ -19,14 +19,13 @@ autorequire:
|
|
19
19
|
bindir: bin
|
20
20
|
cert_chain: []
|
21
21
|
|
22
|
-
date: 2010-09-
|
22
|
+
date: 2010-09-20 00:00:00 -07:00
|
23
23
|
default_executable:
|
24
24
|
dependencies:
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
|
-
type: :development
|
27
|
-
prerelease: false
|
28
26
|
name: activerecord
|
29
|
-
|
27
|
+
prerelease: false
|
28
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
30
29
|
none: false
|
31
30
|
requirements:
|
32
31
|
- - ~>
|
@@ -37,12 +36,12 @@ dependencies:
|
|
37
36
|
- 0
|
38
37
|
- 0
|
39
38
|
version: 3.0.0
|
40
|
-
requirement: *id001
|
41
|
-
- !ruby/object:Gem::Dependency
|
42
39
|
type: :development
|
43
|
-
|
40
|
+
version_requirements: *id001
|
41
|
+
- !ruby/object:Gem::Dependency
|
44
42
|
name: bundler
|
45
|
-
|
43
|
+
prerelease: false
|
44
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
46
45
|
none: false
|
47
46
|
requirements:
|
48
47
|
- - ~>
|
@@ -53,12 +52,12 @@ dependencies:
|
|
53
52
|
- 0
|
54
53
|
- 0
|
55
54
|
version: 1.0.0
|
56
|
-
requirement: *id002
|
57
|
-
- !ruby/object:Gem::Dependency
|
58
55
|
type: :development
|
59
|
-
|
56
|
+
version_requirements: *id002
|
57
|
+
- !ruby/object:Gem::Dependency
|
60
58
|
name: cucumber
|
61
|
-
|
59
|
+
prerelease: false
|
60
|
+
requirement: &id003 !ruby/object:Gem::Requirement
|
62
61
|
none: false
|
63
62
|
requirements:
|
64
63
|
- - ~>
|
@@ -69,12 +68,12 @@ dependencies:
|
|
69
68
|
- 8
|
70
69
|
- 3
|
71
70
|
version: 0.8.3
|
72
|
-
requirement: *id003
|
73
|
-
- !ruby/object:Gem::Dependency
|
74
71
|
type: :development
|
75
|
-
|
72
|
+
version_requirements: *id003
|
73
|
+
- !ruby/object:Gem::Dependency
|
76
74
|
name: jeweler
|
77
|
-
|
75
|
+
prerelease: false
|
76
|
+
requirement: &id004 !ruby/object:Gem::Requirement
|
78
77
|
none: false
|
79
78
|
requirements:
|
80
79
|
- - ~>
|
@@ -85,12 +84,12 @@ dependencies:
|
|
85
84
|
- 4
|
86
85
|
- 0
|
87
86
|
version: 1.4.0
|
88
|
-
requirement: *id004
|
89
|
-
- !ruby/object:Gem::Dependency
|
90
87
|
type: :development
|
91
|
-
|
88
|
+
version_requirements: *id004
|
89
|
+
- !ruby/object:Gem::Dependency
|
92
90
|
name: rake
|
93
|
-
|
91
|
+
prerelease: false
|
92
|
+
requirement: &id005 !ruby/object:Gem::Requirement
|
94
93
|
none: false
|
95
94
|
requirements:
|
96
95
|
- - ">="
|
@@ -99,12 +98,12 @@ dependencies:
|
|
99
98
|
segments:
|
100
99
|
- 0
|
101
100
|
version: "0"
|
102
|
-
requirement: *id005
|
103
|
-
- !ruby/object:Gem::Dependency
|
104
101
|
type: :development
|
105
|
-
|
102
|
+
version_requirements: *id005
|
103
|
+
- !ruby/object:Gem::Dependency
|
106
104
|
name: rdoc
|
107
|
-
|
105
|
+
prerelease: false
|
106
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
108
107
|
none: false
|
109
108
|
requirements:
|
110
109
|
- - ">="
|
@@ -113,12 +112,12 @@ dependencies:
|
|
113
112
|
segments:
|
114
113
|
- 0
|
115
114
|
version: "0"
|
116
|
-
requirement: *id006
|
117
|
-
- !ruby/object:Gem::Dependency
|
118
115
|
type: :development
|
119
|
-
|
116
|
+
version_requirements: *id006
|
117
|
+
- !ruby/object:Gem::Dependency
|
120
118
|
name: rspec
|
121
|
-
|
119
|
+
prerelease: false
|
120
|
+
requirement: &id007 !ruby/object:Gem::Requirement
|
122
121
|
none: false
|
123
122
|
requirements:
|
124
123
|
- - ~>
|
@@ -131,12 +130,12 @@ dependencies:
|
|
131
130
|
- beta
|
132
131
|
- 17
|
133
132
|
version: 2.0.0.beta.17
|
134
|
-
requirement: *id007
|
135
|
-
- !ruby/object:Gem::Dependency
|
136
133
|
type: :development
|
137
|
-
|
134
|
+
version_requirements: *id007
|
135
|
+
- !ruby/object:Gem::Dependency
|
138
136
|
name: sniff
|
139
|
-
|
137
|
+
prerelease: false
|
138
|
+
requirement: &id008 !ruby/object:Gem::Requirement
|
140
139
|
none: false
|
141
140
|
requirements:
|
142
141
|
- - ~>
|
@@ -147,23 +146,24 @@ dependencies:
|
|
147
146
|
- 1
|
148
147
|
- 12
|
149
148
|
version: 0.1.12
|
150
|
-
|
149
|
+
type: :development
|
150
|
+
version_requirements: *id008
|
151
151
|
- !ruby/object:Gem::Dependency
|
152
|
-
type: :runtime
|
153
|
-
prerelease: false
|
154
152
|
name: emitter
|
155
|
-
|
153
|
+
prerelease: false
|
154
|
+
requirement: &id009 !ruby/object:Gem::Requirement
|
156
155
|
none: false
|
157
156
|
requirements:
|
158
157
|
- - ~>
|
159
158
|
- !ruby/object:Gem::Version
|
160
|
-
hash:
|
159
|
+
hash: 7
|
161
160
|
segments:
|
162
161
|
- 0
|
163
162
|
- 0
|
164
|
-
-
|
165
|
-
version: 0.0.
|
166
|
-
|
163
|
+
- 12
|
164
|
+
version: 0.0.12
|
165
|
+
type: :runtime
|
166
|
+
version_requirements: *id009
|
167
167
|
description: A software model in Ruby for the greenhouse gas emissions of a meeting
|
168
168
|
email: andy@rossmeissl.net
|
169
169
|
executables: []
|