residence 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.document ADDED
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
data/.gitignore ADDED
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Andy Rossmeissl
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.rdoc ADDED
@@ -0,0 +1,17 @@
1
+ = residence
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Andy Rossmeissl. See LICENSE for details.
data/Rakefile ADDED
@@ -0,0 +1,54 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "residence"
8
+ gem.summary = %Q{A carbon model}
9
+ gem.description = %Q{A software model in Ruby for the greenhouse gas emissions of an residence}
10
+ gem.email = "andy@rossmeissl.net"
11
+ gem.homepage = "http://github.com/brighterplanet/residence"
12
+ gem.authors = ["Andy Rossmeissl", "Seamus Abshere", "Ian Hough", "Matt Kling"]
13
+ gem.add_development_dependency "thoughtbot-shoulda", ">= 0"
14
+ gem.add_development_dependency 'leap'
15
+ # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
16
+ end
17
+ Jeweler::GemcutterTasks.new
18
+ rescue LoadError
19
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
20
+ end
21
+
22
+ require 'rake/testtask'
23
+ Rake::TestTask.new(:test) do |test|
24
+ test.libs << 'lib' << 'test'
25
+ test.pattern = 'test/**/test_*.rb'
26
+ test.verbose = true
27
+ end
28
+
29
+ begin
30
+ require 'rcov/rcovtask'
31
+ Rcov::RcovTask.new do |test|
32
+ test.libs << 'test'
33
+ test.pattern = 'test/**/test_*.rb'
34
+ test.verbose = true
35
+ end
36
+ rescue LoadError
37
+ task :rcov do
38
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
39
+ end
40
+ end
41
+
42
+ task :test => :check_dependencies
43
+
44
+ task :default => :test
45
+
46
+ require 'rake/rdoctask'
47
+ Rake::RDocTask.new do |rdoc|
48
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
49
+
50
+ rdoc.rdoc_dir = 'rdoc'
51
+ rdoc.title = "residence #{version}"
52
+ rdoc.rdoc_files.include('README*')
53
+ rdoc.rdoc_files.include('lib/**/*.rb')
54
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.0.0
data/lib/residence.rb ADDED
@@ -0,0 +1,544 @@
1
+ module BrighterPlanet
2
+ module Residence
3
+ def self.included(base)
4
+ base.extend ::Leap::Subject
5
+ base.decide :emission, :with => :characteristics do
6
+ committee :emission do
7
+ quorum 'from fuel and electricity use and occupation and residents', :needs => [:fuel_oil_consumed, :natural_gas_consumed, :dirty_electricity_generated, :propane_consumed, :biomass_consumed, :kerosene_consumed, :coal_consumed, :residents, :electricity_emission_factor, :floorspace_estimate, :air_conditioner_use, :active_subtimeframe, :occupation] do |characteristics, timeframe|
8
+ ( characteristics[:fuel_oil_consumed] * ResidenceFuelType.find_by_name('fuel oil').emission_factor +
9
+ characteristics[:natural_gas_consumed] * ResidenceFuelType.find_by_name('natural gas').emission_factor +
10
+ characteristics[:propane_consumed] * ResidenceFuelType.find_by_name('propane').emission_factor +
11
+ characteristics[:biomass_consumed] * ResidenceFuelType.find_by_name('biomass').emission_factor +
12
+ characteristics[:kerosene_consumed] * ResidenceFuelType.find_by_name('kerosene').emission_factor +
13
+ characteristics[:coal_consumed] * ResidenceFuelType.find_by_name('coal').emission_factor +
14
+ characteristics[:dirty_electricity_generated] * characteristics[:electricity_emission_factor] +
15
+ characteristics[:floorspace_estimate] * characteristics[:air_conditioner_use].fugitive_emission * (timeframe / timeframe.year) * characteristics[:occupation]
16
+ ) *
17
+ (characteristics[:active_subtimeframe] / timeframe) / characteristics[:residents]
18
+ end
19
+
20
+ quorum 'default' do
21
+ raise "Residence's default emission quorum should never be called"
22
+ end
23
+ end
24
+
25
+ committee :fuel_oil_consumed do # returns litres
26
+ quorum 'from reports', :needs => :reported_annual_fuel_oil_consumption do |characteristics, timeframe|
27
+ characteristics[:reported_annual_fuel_oil_consumption] * (timeframe / timeframe.year)
28
+ end
29
+ quorum 'from research', :needs => [:predicted_annual_fuel_oil_consumption, :predicted_fuel_shares, :missing_annual_energy, :occupation] do |characteristics, timeframe|
30
+ (characteristics[:predicted_annual_fuel_oil_consumption] + (characteristics[:missing_annual_energy] * characteristics[:predicted_fuel_shares][:fuel_oil]).joules.to(:litres_of_fuel_oil) ) * (timeframe / timeframe.year) * characteristics[:occupation] / fallback.occupation
31
+ end
32
+ end
33
+
34
+ committee :natural_gas_consumed do # returns joules
35
+ quorum 'from reports', :needs => :reported_annual_natural_gas_consumption do |characteristics, timeframe|
36
+ characteristics[:reported_annual_natural_gas_consumption] * (timeframe / timeframe.year)
37
+ end
38
+ quorum 'from research', :needs => [:predicted_annual_natural_gas_consumption, :predicted_fuel_shares, :missing_annual_energy, :occupation] do |characteristics, timeframe|
39
+ (characteristics[:predicted_annual_natural_gas_consumption] + (characteristics[:missing_annual_energy] * characteristics[:predicted_fuel_shares][:natural_gas])) * (timeframe / timeframe.year) * characteristics[:occupation] / fallback.occupation
40
+ end
41
+ end
42
+
43
+ committee :propane_consumed do # returns litres
44
+ quorum 'from reports', :needs => :reported_annual_propane_consumption do |characteristics, timeframe|
45
+ characteristics[:reported_annual_propane_consumption] * (timeframe / timeframe.year)
46
+ end
47
+ quorum 'from research', :needs => [:predicted_annual_propane_consumption, :predicted_fuel_shares, :missing_annual_energy, :occupation] do |characteristics, timeframe|
48
+ (characteristics[:predicted_annual_propane_consumption] + (characteristics[:missing_annual_energy] * characteristics[:predicted_fuel_shares][:propane]).joules.to(:litres_of_propane)) * (timeframe / timeframe.year) * characteristics[:occupation] / fallback.occupation
49
+ end
50
+ end
51
+
52
+ committee :biomass_consumed do # returns joules
53
+ quorum 'from reports', :needs => :reported_annual_biomass_consumption do |characteristics, timeframe|
54
+ characteristics[:reported_annual_biomass_consumption] * (timeframe / timeframe.year)
55
+ end
56
+ quorum 'from research', :needs => [:predicted_annual_biomass_consumption, :predicted_fuel_shares, :missing_annual_energy, :occupation] do |characteristics, timeframe|
57
+ (characteristics[:predicted_annual_biomass_consumption] + (characteristics[:missing_annual_energy] * characteristics[:predicted_fuel_shares][:biomass])) * (timeframe / timeframe.year) * characteristics[:occupation] / fallback.occupation
58
+ end
59
+ end
60
+
61
+ committee :kerosene_consumed do # returns litres
62
+ quorum 'from reports', :needs => :reported_annual_kerosene_consumption do |characteristics, timeframe|
63
+ characteristics[:reported_annual_kerosene_consumption] * (timeframe / timeframe.year)
64
+ end
65
+ quorum 'from research', :needs => [:predicted_annual_kerosene_consumption, :predicted_fuel_shares, :missing_annual_energy, :occupation] do |characteristics, timeframe|
66
+ (characteristics[:predicted_annual_kerosene_consumption] + (characteristics[:missing_annual_energy] * characteristics[:predicted_fuel_shares][:kerosene]).joules.to(:litres_of_kerosene)) * (timeframe / timeframe.year) * characteristics[:occupation] / fallback.occupation
67
+ end
68
+ end
69
+
70
+ committee :coal_consumed do # returns kg
71
+ quorum 'from reports', :needs => :reported_annual_coal_consumption do |characteristics, timeframe|
72
+ characteristics[:reported_annual_coal_consumption] * (timeframe / timeframe.year)
73
+ end
74
+ quorum 'from research', :needs => [:predicted_annual_coal_consumption, :predicted_fuel_shares, :missing_annual_energy, :occupation] do |characteristics, timeframe|
75
+ (characteristics[:predicted_annual_coal_consumption] + (characteristics[:missing_annual_energy] * characteristics[:predicted_fuel_shares][:coal]).joules.to(:kilograms_of_coal)) * (timeframe / timeframe.year) * characteristics[:occupation] / fallback.occupation
76
+ end
77
+ end
78
+
79
+ committee :dirty_electricity_generated do
80
+ quorum 'from electricity generated and green electricity', :needs => [:electricity_generated, :green_electricity] do |characteristics|
81
+ characteristics[:electricity_generated] * (1.0 - characteristics[:green_electricity])
82
+ end
83
+ end
84
+
85
+ committee :green_electricity do
86
+ quorum 'default' do
87
+ fallback.green_electricity
88
+ end
89
+ end
90
+
91
+ committee :electricity_generated do # returns kWh
92
+ quorum 'from electricity used and loss rate', :needs => [:electricity_used, :electricity_loss_rate] do |characteristics|
93
+ characteristics[:electricity_used] / (1.0 - characteristics[:electricity_loss_rate])
94
+ end
95
+ end
96
+
97
+ committee :electricity_used do # returns kWh
98
+ quorum 'from reports', :needs => :reported_annual_electricity_use do |characteristics, timeframe|
99
+ characteristics[:reported_annual_electricity_use] * (timeframe / timeframe.year)
100
+ end
101
+
102
+ quorum 'from research', :needs => [:predicted_annual_electricity_use, :predicted_fuel_shares, :missing_annual_energy, :occupation] do |characteristics, timeframe|
103
+ (characteristics[:predicted_annual_electricity_use] + ((characteristics[:missing_annual_energy] * characteristics[:predicted_fuel_shares][:electricity]).joules.to(:kilowatt_hours))) * (timeframe / timeframe.year) * characteristics[:occupation] / fallback.occupation
104
+ end
105
+ end
106
+
107
+ committee :missing_annual_energy do # returns joules
108
+ quorum 'from fuel reports', :needs => [:predicted_annual_fuel_oil_consumption, :predicted_annual_natural_gas_consumption, :predicted_annual_propane_consumption, :predicted_annual_kerosene_consumption, :predicted_annual_biomass_consumption, :predicted_annual_coal_consumption, :predicted_annual_electricity_use], :appreciates => [:reported_annual_fuel_oil_consumption, :reported_annual_natural_gas_consumption, :reported_annual_propane_consumption, :reported_annual_kerosene_consumption, :reported_annual_biomass_consumption, :reported_annual_coal_consumption, :reported_annual_electricity_use] do |characteristics|
109
+ energy = 0
110
+ if characteristics[:reported_annual_fuel_oil_consumption] and characteristics[:reported_annual_fuel_oil_consumption].zero?
111
+ energy += characteristics[:predicted_annual_fuel_oil_consumption].litres_of_fuel_oil.to :joules
112
+ end
113
+ if characteristics[:reported_annual_natural_gas_consumption] and characteristics[:reported_annual_natural_gas_consumption].zero?
114
+ energy += characteristics[:predicted_annual_natural_gas_consumption]
115
+ end
116
+ if characteristics[:reported_annual_propane_consumption] and characteristics[:reported_annual_propane_consumption].zero?
117
+ energy += characteristics[:predicted_annual_propane_consumption].litres_of_propane.to :joules
118
+ end
119
+ if characteristics[:reported_annual_kerosene_consumption] and characteristics[:reported_annual_kerosene_consumption].zero?
120
+ energy += characteristics[:predicted_annual_kerosene_consumption].litres_of_kerosene.to :joules
121
+ end
122
+ if characteristics[:reported_annual_biomass_consumption] and characteristics[:reported_annual_biomass_consumption].zero?
123
+ energy += characteristics[:predicted_annual_biomass_consumption]
124
+ end
125
+ if characteristics[:reported_annual_coal_consumption] and characteristics[:reported_annual_coal_consumption].zero?
126
+ energy += characteristics[:predicted_annual_coal_consumption].kilograms_of_coal.to :joules
127
+ end
128
+ if characteristics[:reported_annual_electricity_use] and characteristics[:reported_annual_electricity_use].zero?
129
+ energy += characteristics[:predicted_annual_electricity_use].kilowatt_hours.to :joules
130
+ end
131
+ energy
132
+ end
133
+ end
134
+
135
+ committee :electricity_loss_rate do # returns percentage
136
+ quorum 'from egrid region', :needs => :egrid_region do |characteristics|
137
+ characteristics[:egrid_region].loss_factor
138
+ end
139
+
140
+ quorum 'default' do
141
+ EgridRegion.fallback.loss_factor
142
+ end
143
+ end
144
+
145
+ committee :electricity_emission_factor do # returns kg CO2 / kWh
146
+ quorum 'from egrid subregion', :needs => :egrid_subregion do |characteristics|
147
+ characteristics[:egrid_subregion].electricity_emission_factor
148
+ end
149
+
150
+ quorum 'default' do
151
+ EgridSubregion.fallback.electricity_emission_factor
152
+ end
153
+ end
154
+
155
+ committee :egrid_region do
156
+ quorum 'from egrid subregion', :needs => :egrid_subregion do |characteristics|
157
+ characteristics[:egrid_subregion].egrid_region
158
+ end
159
+ end
160
+
161
+ committee :egrid_subregion do
162
+ quorum 'from_zip_code', :needs => :zip_code do |characteristics|
163
+ characteristics[:zip_code].egrid_subregion
164
+ end
165
+ end
166
+
167
+ committee :occupation do
168
+ quorum 'default' do
169
+ fallback.occupation
170
+ end
171
+ end
172
+
173
+ committee :residents do
174
+ quorum 'from cohort', :needs => :cohort do |characteristics|
175
+ characteristics[:cohort].weighted_average :residents
176
+ end
177
+
178
+ quorum 'default' do
179
+ fallback.residents_before_type_cast
180
+ end
181
+ end
182
+
183
+ committee :air_conditioner_use do
184
+ quorum 'default' do
185
+ AirConditionerUse.fallback
186
+ end
187
+ end
188
+
189
+ committee :predicted_fuel_shares do # returns an array of percentages
190
+ quorum 'from research', :needs => [:predicted_annual_energy_consumption, :predicted_annual_fuel_oil_consumption, :predicted_annual_natural_gas_consumption, :predicted_annual_propane_consumption, :predicted_annual_kerosene_consumption, :predicted_annual_biomass_consumption, :predicted_annual_coal_consumption, :predicted_annual_electricity_use] do |characteristics|
191
+ {
192
+ :fuel_oil => characteristics[:predicted_annual_fuel_oil_consumption].litres_of_fuel_oil.to(:joules) / characteristics[:predicted_annual_energy_consumption],
193
+ :natural_gas => characteristics[:predicted_annual_natural_gas_consumption] / characteristics[:predicted_annual_energy_consumption],
194
+ :propane => characteristics[:predicted_annual_propane_consumption].litres_of_propane.to(:joules) / characteristics[:predicted_annual_energy_consumption],
195
+ :kerosene => characteristics[:predicted_annual_kerosene_consumption].litres_of_kerosene.to(:joules) / characteristics[:predicted_annual_energy_consumption],
196
+ :biomass => characteristics[:predicted_annual_biomass_consumption] / characteristics[:predicted_annual_energy_consumption],
197
+ :coal => characteristics[:predicted_annual_coal_consumption].kilograms_of_coal.to(:joules) / characteristics[:predicted_annual_energy_consumption],
198
+ :electricity => characteristics[:predicted_annual_electricity_use].kilowatt_hours.to(:joules) / characteristics[:predicted_annual_energy_consumption]
199
+ }
200
+ end
201
+ end
202
+
203
+ committee :predicted_annual_energy_consumption do # returns BTUs
204
+ quorum 'from research', :needs => [:predicted_annual_fuel_oil_consumption, :predicted_annual_natural_gas_consumption, :predicted_annual_propane_consumption, :predicted_annual_kerosene_consumption, :predicted_annual_biomass_consumption, :predicted_annual_coal_consumption, :predicted_annual_electricity_use] do |characteristics|
205
+ energy = 0
206
+ energy += characteristics[:predicted_annual_fuel_oil_consumption].litres_of_fuel_oil.to :joules
207
+ energy += characteristics[:predicted_annual_natural_gas_consumption]
208
+ energy += characteristics[:predicted_annual_propane_consumption].litres_of_propane.to :joules
209
+ energy += characteristics[:predicted_annual_kerosene_consumption].litres_of_kerosene.to :joules
210
+ energy += characteristics[:predicted_annual_biomass_consumption]
211
+ energy += characteristics[:predicted_annual_coal_consumption].kilograms_of_coal.to :joules
212
+ energy += characteristics[:predicted_annual_electricity_use].kilowatt_hours.to :joules
213
+ end
214
+ end
215
+
216
+ committee :reported_annual_fuel_oil_consumption do # returns litres
217
+ quorum 'from volume estimate', :needs => :annual_fuel_oil_volume_estimate do |characteristics|
218
+ characteristics[:annual_fuel_oil_volume_estimate]
219
+ end
220
+
221
+ quorum 'from cost', :needs => :annual_fuel_oil_cost, :appreciates => :state do |characteristics, timeframe|
222
+ relaxations = []
223
+ relaxations << { :timeframe => timeframe, :location => characteristics[:state] } if characteristics[:state]
224
+ relaxations << { :timeframe => timeframe.last_year, :location => characteristics[:state] } if characteristics[:state]
225
+ relaxations << { :timeframe => timeframe, :location => Country.united_states }
226
+ relaxations << { :timeframe => timeframe.last_year, :location => Country.united_states }
227
+ if price_per_unit = ResidenceFuelType[:fuel_oil].price_per_unit(relaxations)
228
+ characteristics[:annual_fuel_oil_cost] / price_per_unit
229
+ else
230
+ nil
231
+ end
232
+ end
233
+ end
234
+
235
+ committee :predicted_annual_fuel_oil_consumption do # returns litres
236
+ quorum 'from cohort', :needs => :cohort do |characteristics|
237
+ characteristics[:cohort].weighted_average(%w(heating_space heating_water appliances).map { |purpose| "annual_energy_from_fuel_oil_for_#{purpose}".to_sym }).to_f.joules.to(:litres_of_fuel_oil)
238
+ end
239
+
240
+ quorum 'default' do
241
+ fallback.annual_fuel_oil_volume_estimate
242
+ end
243
+ end
244
+
245
+ committee :reported_annual_natural_gas_consumption do # returns joules
246
+ quorum 'from volume estimate', :needs => :monthly_natural_gas_volume_estimate do |characteristics|
247
+ characteristics[:monthly_natural_gas_volume_estimate] * 12
248
+ end
249
+
250
+ quorum 'from cost', :needs => :monthly_natural_gas_cost, :appreciates => :state do |characteristics, timeframe|
251
+ relaxations = []
252
+ relaxations << { :timeframe => timeframe, :location => characteristics[:state] } if characteristics[:state]
253
+ relaxations << { :timeframe => timeframe.last_year, :location => characteristics[:state] } if characteristics[:state]
254
+ relaxations << { :timeframe => timeframe, :location => Country.united_states }
255
+ relaxations << { :timeframe => timeframe.last_year, :location => Country.united_states }
256
+ if price_per_unit = ResidenceFuelType[:natural_gas].price_per_unit(relaxations) #FIXME joules vs. cubic metres issue
257
+ characteristics[:monthly_natural_gas_cost] * 12 / price_per_unit
258
+ else
259
+ nil
260
+ end
261
+ end
262
+ end
263
+
264
+ committee :predicted_annual_natural_gas_consumption do # returns joules
265
+ quorum 'from cohort', :needs => :cohort do |characteristics|
266
+ characteristics[:cohort].weighted_average(%w(heating_space heating_water appliances).map { |purpose| "annual_energy_from_natural_gas_for_#{purpose}".to_sym }).to_f
267
+ end
268
+
269
+ quorum 'default' do
270
+ fallback.monthly_natural_gas_volume_estimate * 12
271
+ end
272
+ end
273
+
274
+ committee :reported_annual_propane_consumption do # returns litres
275
+ quorum 'from volume estimate', :needs => :annual_propane_volume_estimate do |characteristics|
276
+ characteristics[:annual_propane_volume_estimate]
277
+ end
278
+
279
+ quorum 'from cost', :needs => :annual_propane_cost, :appreciates => :state do |characteristics, timeframe|
280
+ relaxations = []
281
+ relaxations << { :timeframe => timeframe, :location => characteristics[:state].petroleum_administration_for_defense_district } if characteristics[:state]
282
+ relaxations << { :timeframe => timeframe.last_year, :location => characteristics[:state].petroleum_administration_for_defense_district } if characteristics[:state]
283
+ relaxations << { :timeframe => timeframe, :location => Country.united_states }
284
+ relaxations << { :timeframe => timeframe.last_year, :location => Country.united_states }
285
+ if price_per_unit = ResidenceFuelType[:propane].price_per_unit(relaxations)
286
+ characteristics[:annual_propane_cost] / price_per_unit
287
+ else
288
+ nil
289
+ end
290
+ end
291
+ end
292
+
293
+ committee :predicted_annual_propane_consumption do # returns litres
294
+ quorum 'from cohort', :needs => :cohort do |characteristics|
295
+ characteristics[:cohort].weighted_average(%w(heating_space heating_water appliances).map { |purpose| "annual_energy_from_propane_for_#{purpose}".to_sym }).to_f.joules.to(:litres_of_propane)
296
+ end
297
+
298
+ quorum 'default' do
299
+ fallback.annual_propane_volume_estimate
300
+ end
301
+ end
302
+
303
+ committee :reported_annual_kerosene_consumption do # returns litres
304
+ quorum 'from volume estimate', :needs => :annual_kerosene_volume_estimate do |characteristics|
305
+ characteristics[:annual_kerosene_volume_estimate]
306
+ end
307
+ end
308
+
309
+ committee :predicted_annual_kerosene_consumption do # returns litres
310
+ quorum 'from cohort', :needs => :cohort do |characteristics|
311
+ characteristics[:cohort].weighted_average(:annual_energy_from_kerosene).to_f.joules.to(:litres_of_kerosene)
312
+ end
313
+
314
+ quorum 'default' do
315
+ fallback.annual_kerosene_volume_estimate
316
+ end
317
+ end
318
+
319
+ committee :reported_annual_biomass_consumption do # returns joules
320
+ quorum 'from volume estimate', :needs => :annual_wood_volume_estimate do |characteristics|
321
+ characteristics[:annual_wood_volume_estimate]
322
+ end
323
+ end
324
+
325
+ committee :predicted_annual_biomass_consumption do # returns joules
326
+ quorum 'from cohort', :needs => :cohort do |characteristics|
327
+ characteristics[:cohort].weighted_average(:annual_energy_from_wood)
328
+ end
329
+
330
+ quorum 'default' do
331
+ fallback.annual_wood_volume_estimate
332
+ end
333
+ end
334
+
335
+ committee :reported_annual_coal_consumption do # returns kg
336
+ quorum 'from volume estimate', :needs => :annual_coal_volume_estimate do |characteristics|
337
+ characteristics[:annual_coal_volume_estimate]
338
+ end
339
+ end
340
+
341
+ committee :predicted_annual_coal_consumption do # returns kg
342
+ quorum 'default' do
343
+ fallback.annual_coal_volume_estimate
344
+ end
345
+ end
346
+
347
+ committee :reported_annual_electricity_use do # returns kWh
348
+ quorum 'from use estimate', :needs => :monthly_electricity_use_estimate do |characteristics|
349
+ characteristics[:monthly_electricity_use_estimate] * 12
350
+ end
351
+
352
+ quorum 'from cost', :needs => :monthly_electricity_cost, :appreciates => :state do |characteristics, timeframe|
353
+ relaxations = []
354
+ relaxations << { :timeframe => timeframe, :location => characteristics[:state] } if characteristics[:state]
355
+ relaxations << { :timeframe => timeframe.last_year, :location => characteristics[:state] } if characteristics[:state]
356
+ relaxations << { :timeframe => timeframe, :location => Country.united_states }
357
+ relaxations << { :timeframe => timeframe.last_year, :location => Country.united_states }
358
+ if price_per_unit = ResidenceFuelType[:electricity].price_per_unit(relaxations)
359
+ characteristics[:monthly_electricity_cost] * 12 / price_per_unit
360
+ else
361
+ nil
362
+ end
363
+ end
364
+ end
365
+
366
+ committee :predicted_annual_electricity_use do # returns kWh
367
+ quorum 'from cohort', :needs => :cohort, :appreciates => [:clothes_machine_use, :refrigerator_count, :freezer_count, :dishwasher_use, :lighting_efficiency] do |characteristics|
368
+ cohort = characteristics[:cohort]
369
+ energy = cohort.weighted_average([:annual_energy_from_electricity_for_clothes_driers,
370
+ :annual_energy_from_electricity_for_dishwashers,
371
+ :annual_energy_from_electricity_for_freezers,
372
+ :annual_energy_from_electricity_for_refrigerators,
373
+ :annual_energy_from_electricity_for_air_conditioners,
374
+ :annual_energy_from_electricity_for_heating_space,
375
+ :annual_energy_from_electricity_for_heating_water,
376
+ :annual_energy_from_electricity_for_other_appliances]).to_f
377
+
378
+ if clothes_machine_use = characteristics[:clothes_machine_use]
379
+ energy -= cohort.weighted_average(:annual_energy_from_electricity_for_clothes_driers)
380
+ clothes_machine_use_cohort = ResidentialEnergyConsumptionSurveyResponse.big_cohort(characteristics.slice(*([:clothes_machine_use].push(*ResidentialEnergyConsumptionSurveyResponse::INPUT_CHARACTERISTICS))), ResidentialEnergyConsumptionSurveyResponse::SUBCOHORT_THRESHOLD)
381
+ if clothes_machine_use_cohort.any?
382
+ energy += clothes_machine_use_cohort.weighted_average(:annual_energy_from_electricity_for_clothes_driers).to_f
383
+ else
384
+ energy += charcteristics[:clothes_machine_use].annual_energy_from_electricity_for_clothes_driers
385
+ end
386
+ end
387
+
388
+ if refrigerator_count = characteristics[:refrigerator_count]
389
+ energy -= cohort.weighted_average(:annual_energy_from_electricity_for_refrigerators)
390
+ if refrigerator_count == 0
391
+ energy += 0
392
+ else
393
+ refrigerator_count_subcohort = ResidentialEnergyConsumptionSurveyResponse.big_cohort(characteristics.slice(*([:refrigerator_count].push(*ResidentialEnergyConsumptionSurveyResponse::INPUT_CHARACTERISTICS))), ResidentialEnergyConsumptionSurveyResponse::SUBCOHORT_THRESHOLD)
394
+ if refrigerator_count_subcohort.any?
395
+ energy += refrigerator_count_subcohort.weighted_average(:annual_energy_from_electricity_for_refrigerators).to_f
396
+ else
397
+ energy += refrigerator_count * ResidenceAppliance.annual_energy_from_electricity_for(:refrigerators)
398
+ end
399
+ end
400
+ end
401
+
402
+ if freezer_count = characteristics[:freezer_count]
403
+ energy -= cohort.weighted_average(:annual_energy_from_electricity_for_freezers)
404
+ if freezer_count == 0
405
+ energy += 0
406
+ else
407
+ freezer_count_subcohort = ResidentialEnergyConsumptionSurveyResponse.big_cohort(characteristics.slice(*([:freezer_count].push(*ResidentialEnergyConsumptionSurveyResponse::INPUT_CHARACTERISTICS))), ResidentialEnergyConsumptionSurveyResponse::SUBCOHORT_THRESHOLD)
408
+ if freezer_count_subcohort.any?
409
+ energy += freezer_count_subcohort.weighted_average(:annual_energy_from_electricity_for_freezers).to_f
410
+ else
411
+ energy += freezer_count * ResidenceAppliance.annual_energy_from_electricity_for(:freezers)
412
+ end
413
+ end
414
+ end
415
+
416
+ if dishwasher_use = characteristics[:dishwasher_use]
417
+ energy -= cohort.weighted_average(:annual_energy_from_electricity_for_dishwashers)
418
+ dishwasher_use_cohort = ResidentialEnergyConsumptionSurveyResponse.big_cohort(characteristics.slice(*([:dishwasher_use].push(*ResidentialEnergyConsumptionSurveyResponse::INPUT_CHARACTERISTICS))), ResidentialEnergyConsumptionSurveyResponse::SUBCOHORT_THRESHOLD)
419
+ if dishwasher_use_cohort.any?
420
+ energy += dishwasher_use_cohort.weighted_average(:annual_energy_from_electricity_for_dishwashers).to_f
421
+ else
422
+ energy += characteristics[:dishwasher_use].annual_energy_from_electricity_for_dishwashers
423
+ end
424
+ end
425
+
426
+ if lighting_efficiency = characteristics[:lighting_efficiency]
427
+ lighting_electricity_use_in_cohort =
428
+ cohort.weighted_average(:lighting_efficiency) * cohort.weighted_average(:lighting_use) * research(:efficient_lightbulb_power) +
429
+ (1 - cohort.weighted_average(:lighting_efficiency)) * cohort.weighted_average(:lighting_use) * research(:standard_lightbulb_power)
430
+ energy -= lighting_electricity_use_in_cohort.watt_hours.to :joules
431
+ lighting_electricity_use_in_residence =
432
+ lighting_efficiency * cohort.weighted_average(:lighting_use) * research(:efficient_lightbulb_power) +
433
+ (1 - lighting_efficiency) * cohort.weighted_average(:lighting_use) * research(:standard_lightbulb_power)
434
+ energy += lighting_electricity_use_in_residence.watt_hours.to :joules
435
+ end
436
+
437
+ energy.joules.to(:kilowatt_hours)
438
+ end
439
+
440
+ quorum 'default' do
441
+ fallback.monthly_electricity_use_estimate * 12
442
+ end
443
+ end
444
+
445
+ committee :active_subtimeframe do
446
+ quorum 'from acquisition and retirement', :needs => [:acquisition, :retirement] do |characteristics, timeframe|
447
+ Timeframe.constrained_new characteristics[:acquisition].to_date, characteristics[:retirement].to_date, timeframe
448
+ end
449
+ end
450
+
451
+ committee :acquisition do
452
+ quorum 'from construction year', :needs => :construction_year do |characteristics|
453
+ #FIXME this is an imperfect substitution for a line in https://app1.yerba.brighterplanet.com/changesets/9463
454
+ characteristics[:construction_year] - 1.year
455
+ end
456
+ quorum 'from retirement', :appreciates => :retirement do |characteristics, timeframe|
457
+ [ timeframe.from, characteristics[:retirement] ].compact.min
458
+ end
459
+ end
460
+
461
+ committee :retirement do
462
+ quorum 'from acquisition', :appreciates => :acquisition do |characteristics, timeframe|
463
+ [ timeframe.to, characteristics[:acquisition] ].compact.max
464
+ end
465
+ end
466
+
467
+ # This is kindof "hacky"
468
+ # As implemented, this needs to be above floorspace committee or else cohort will always
469
+ # use the fallback
470
+ committee :floorspace_estimate do
471
+ quorum 'from cohort', :needs => :cohort do |characteristics|
472
+ characteristics[:cohort].weighted_average :floorspace
473
+ end
474
+
475
+ quorum 'default' do
476
+ fallback.floorspace_estimate
477
+ end
478
+ end
479
+
480
+ committee :cohort do
481
+ quorum 'from residential energy consumption survey', :appreciates => ResidentialEnergyConsumptionSurveyResponse::INPUT_CHARACTERISTICS do |characteristics|
482
+ cohort = ResidentialEnergyConsumptionSurveyResponse.big_cohort characteristics
483
+ if cohort.any?
484
+ cohort
485
+ else
486
+ nil
487
+ end
488
+ end
489
+ end
490
+
491
+ committee :bathrooms do
492
+ quorum 'from fractional bathroom counts', :needs => [:full_bathrooms, :half_bathrooms] do |characteristics|
493
+ characteristics[:full_bathrooms] + 0.5 * characteristics[:half_bathrooms]
494
+ end
495
+ end
496
+
497
+ committee :census_region do
498
+ quorum 'from census division', :needs => :census_division do |characteristics|
499
+ characteristics[:census_division].census_region
500
+ end
501
+ end
502
+
503
+ committee :census_division do
504
+ quorum 'from state', :needs => :state do |characteristics|
505
+ characteristics[:state].census_division
506
+ end
507
+ end
508
+
509
+ committee :state do
510
+ quorum 'from climate division', :needs => :climate_division do |characteristics|
511
+ characteristics[:climate_division].state
512
+ end
513
+ end
514
+
515
+ committee :floorspace do # returns a Range of floorspaces
516
+ quorum 'from floorspace estimate', :needs => :floorspace_estimate do |characteristics|
517
+ floorspace_estimate = characteristics[:floorspace_estimate]
518
+ (floorspace_estimate - 50)..(floorspace_estimate + 50)
519
+ end
520
+ end
521
+
522
+ committee :heating_degree_days do # returns a Range of degree-days
523
+ quorum 'from climate division', :needs => :climate_division do |characteristics|
524
+ days = characteristics[:climate_division].heating_degree_days
525
+ (days - ClimateDivision::RADIUS)..(days + ClimateDivision::RADIUS)
526
+ end
527
+ end
528
+
529
+ committee :cooling_degree_days do
530
+ quorum 'from climate division', :needs => :climate_division do |characteristics|
531
+ days = characteristics[:climate_division].cooling_degree_days
532
+ (days - ClimateDivision::RADIUS)..(days + ClimateDivision::RADIUS)
533
+ end
534
+ end
535
+
536
+ committee :climate_division do
537
+ quorum 'from zip code', :needs => :zip_code do |characteristics|
538
+ characteristics[:zip_code].climate_division
539
+ end
540
+ end
541
+ end
542
+ end
543
+ end
544
+ end
data/test/helper.rb ADDED
@@ -0,0 +1,10 @@
1
+ require 'rubygems'
2
+ require 'test/unit'
3
+ require 'shoulda'
4
+
5
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
6
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
7
+ require 'residence'
8
+
9
+ class Test::Unit::TestCase
10
+ end
@@ -0,0 +1,7 @@
1
+ require 'helper'
2
+
3
+ class TestResidence < Test::Unit::TestCase
4
+ should "probably rename this file and start testing for real" do
5
+ flunk "hey buddy, you should probably rename this file and start testing for real"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,98 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: residence
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 0
8
+ - 0
9
+ version: 0.0.0
10
+ platform: ruby
11
+ authors:
12
+ - Andy Rossmeissl
13
+ - Seamus Abshere
14
+ - Ian Hough
15
+ - Matt Kling
16
+ autorequire:
17
+ bindir: bin
18
+ cert_chain: []
19
+
20
+ date: 2010-06-10 00:00:00 -04:00
21
+ default_executable:
22
+ dependencies:
23
+ - !ruby/object:Gem::Dependency
24
+ name: thoughtbot-shoulda
25
+ prerelease: false
26
+ requirement: &id001 !ruby/object:Gem::Requirement
27
+ requirements:
28
+ - - ">="
29
+ - !ruby/object:Gem::Version
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :development
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: leap
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - ">="
41
+ - !ruby/object:Gem::Version
42
+ segments:
43
+ - 0
44
+ version: "0"
45
+ type: :development
46
+ version_requirements: *id002
47
+ description: A software model in Ruby for the greenhouse gas emissions of an residence
48
+ email: andy@rossmeissl.net
49
+ executables: []
50
+
51
+ extensions: []
52
+
53
+ extra_rdoc_files:
54
+ - LICENSE
55
+ - README.rdoc
56
+ files:
57
+ - .document
58
+ - .gitignore
59
+ - LICENSE
60
+ - README.rdoc
61
+ - Rakefile
62
+ - VERSION
63
+ - lib/residence.rb
64
+ - test/helper.rb
65
+ - test/test_residence.rb
66
+ has_rdoc: true
67
+ homepage: http://github.com/brighterplanet/residence
68
+ licenses: []
69
+
70
+ post_install_message:
71
+ rdoc_options:
72
+ - --charset=UTF-8
73
+ require_paths:
74
+ - lib
75
+ required_ruby_version: !ruby/object:Gem::Requirement
76
+ requirements:
77
+ - - ">="
78
+ - !ruby/object:Gem::Version
79
+ segments:
80
+ - 0
81
+ version: "0"
82
+ required_rubygems_version: !ruby/object:Gem::Requirement
83
+ requirements:
84
+ - - ">="
85
+ - !ruby/object:Gem::Version
86
+ segments:
87
+ - 0
88
+ version: "0"
89
+ requirements: []
90
+
91
+ rubyforge_project:
92
+ rubygems_version: 1.3.6
93
+ signing_key:
94
+ specification_version: 3
95
+ summary: A carbon model
96
+ test_files:
97
+ - test/helper.rb
98
+ - test/test_residence.rb