residence 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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