sandy 0.0.5 → 0.0.6

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -15,3 +15,4 @@ spec/reports
15
15
  test/tmp
16
16
  test/version_tmp
17
17
  tmp
18
+ .DS_Store
data/.travis.yml CHANGED
@@ -1,4 +1,8 @@
1
1
  language: ruby
2
+ branches:
3
+ only:
4
+ - master
5
+ - stable
2
6
  rvm:
3
7
  - 1.9.3
4
8
  gemfile:
data/README.md CHANGED
@@ -1,43 +1,39 @@
1
- # Sandy
2
-
3
- Rubygem for consuming power outage data for the Greater New York area. Currently supports ConEd.
1
+ # Sandy
4
2
  [![Build Status](https://secure.travis-ci.org/ckundo/sandy.png)](https://travis-ci.org/ckundo/sandy)
3
+ [![Code Climate](https://codeclimate.com/badge.png)](https://codeclimate.com/github/ckundo/sandy)
5
4
 
6
- ## Installation
7
-
8
- Add this line to your application's Gemfile:
9
-
10
- gem 'sandy'
11
-
12
- And then execute:
13
-
14
- $ bundle
15
-
16
- Or install it yourself as:
17
-
18
- $ gem install sandy
5
+ Sandy is a rubygem for consuming power outage data for the Greater New York area. For a given area, retrieve number of outages,
6
+ as well as total customers, lat/lng, and estimated time of recovery (depending on the provider).
19
7
 
8
+ Currently supports ConEd (NYC), LIPA (Long Island), and PSEG (NJ).
20
9
 
21
10
  ## Usage
22
11
 
23
- ### ConEd
12
+ ### Providers
13
+
14
+ Sandy::Provider::LIPA::Report.new
15
+ Sandy::Provider::ConEd::Report.new
24
16
 
25
- #### Polling
17
+ ### Areas
26
18
 
27
- The ConEd outage feed is only updated every 15 minutes. Repeated polling won't get you new results.
19
+ Area#name
20
+ Area#customers_affected
21
+ Area#region
22
+ Area#latitude
23
+ Area#longitude
24
+ Area#total_customers
25
+ Area#estimated_recovery_time
28
26
 
29
- #### Example
27
+ ### Example
30
28
 
31
29
  report = Sandy::Provider::ConEd::Report.new
32
30
 
33
- Regions:
34
-
35
- regions = report.regions
36
- regions.each do |region|
37
- puts "#{region.name}, #{region.customers_affected}"
31
+ areas = report.areas
32
+ areas.each do |area|
33
+ puts "#{area.name}, #{area.customers_affected}"
38
34
  end
39
35
 
40
- =>
36
+ # =>
41
37
 
42
38
  Bronx, 28644
43
39
  Brooklyn, 37016
@@ -46,31 +42,23 @@ Regions:
46
42
  Staten Island, 58043
47
43
  Westchester, 123571
48
44
 
49
- Neighborhoods:
45
+ ### A note on Polling
50
46
 
51
- neighborhoods = report.neighborhoods
52
- neighborhoods.each do |neighborhood|
53
- puts "#{neighborhood.name} (#{neighborhood.latitude}, #{neighborhood.longitude}) #{neighborhood.customers_affected} out of #{neighborhood.total_customers}"
54
- end
47
+ The ConEd outage feed is only updated every 15 minutes. Repeated polling won't get you new results.
55
48
 
56
- =>
49
+ ## Installation
57
50
 
58
- Central Bronx (40.82, -73.86) 26 out of 44452
59
- Fordham (40.86, -73.9) 164 out of 114772
60
- Northeast Bronx (40.87, -73.82) 13139 out of 79942
61
- Riverdale (40.89, -73.9) 3801 out of 34772
62
- Southeast Bronx (40.83, -73.82) 5919 out of 89736
63
- ...
51
+ Add this line to your application's Gemfile:
64
52
 
65
- #### Methods
53
+ gem 'sandy'
66
54
 
67
- Area#name
68
- Area#customers_affected
69
- Area#region - returns a string of the parent region name for a neighborhood)
70
- Area#latitude
71
- Area#longitude
72
- Area#total_customers
73
- Area#estimated_recovery_time
55
+ And then execute:
56
+
57
+ $ bundle
58
+
59
+ Or install it yourself as:
60
+
61
+ $ gem install sandy
74
62
 
75
63
  ## Contributing
76
64
 
@@ -79,3 +67,7 @@ Neighborhoods:
79
67
  3. Commit your changes (`git commit -am 'Add some feature'`)
80
68
  4. Push to the branch (`git push origin my-new-feature`)
81
69
  5. Create new Pull Request
70
+
71
+ ## Powered by the sandy gem
72
+
73
+ * [NYC Power Status](http://nycpowerstatus.com/) - vizualizations of power outages by neighborhood in NYC
data/lib/sandy/area.rb CHANGED
@@ -1,7 +1,8 @@
1
1
  module Sandy
2
2
  class Area
3
3
  attr_reader :name,
4
- :region,
4
+ :parent,
5
+ :children,
5
6
  :customers_affected,
6
7
  :latitude,
7
8
  :longitude,
@@ -11,11 +12,27 @@ module Sandy
11
12
  def initialize(customers_affected, location, options = {})
12
13
  @name = location
13
14
  @customers_affected = customers_affected
14
- @region = options[:region]
15
+ @parent = options[:parent]
15
16
  @total_customers = options[:total_customers]
16
17
  @latitude = options[:latitude]
17
18
  @longitude = options[:longitude]
18
19
  @estimated_recovery_time = options[:estimated_recovery_time]
20
+ @children = options[:children] || []
21
+ end
22
+
23
+ def to_s
24
+ @name
25
+ end
26
+
27
+ def to_json(*a)
28
+ {"name" => @name,
29
+ "customers_affected" => @customers_affected,
30
+ "parent" => @parent.to_s,
31
+ "total_customers" => @total_customers,
32
+ "latitude" => @latitude,
33
+ "longitude" => @longitude,
34
+ "estimated_recovery_time" => @longitude,
35
+ "children" => @children }.to_json
19
36
  end
20
37
  end
21
38
  end
@@ -1,5 +1,7 @@
1
+ require "sandy/providers/coordinate_cache"
1
2
  require "sandy/providers/coned"
2
3
  require "sandy/providers/lipa"
4
+ require "sandy/providers/pseg"
3
5
 
4
6
  module Sandy
5
7
  module Provider
@@ -0,0 +1,361 @@
1
+ ---
2
+ bronx:
3
+ :latitude: '40.85'
4
+ :longitude: '-73.866667'
5
+ central bronx:
6
+ :latitude: '40.8378381'
7
+ :longitude: '-73.8629236'
8
+ fordham:
9
+ :latitude: '40.8606677'
10
+ :longitude: '-73.8910629'
11
+ northeast bronx:
12
+ :latitude: '40.85'
13
+ :longitude: '-73.866667'
14
+ riverdale:
15
+ :latitude: '40.8940853'
16
+ :longitude: '-73.9109977'
17
+ southeast bronx:
18
+ :latitude: '40.85'
19
+ :longitude: '-73.866667'
20
+ west bronx:
21
+ :latitude: '40.8519547'
22
+ :longitude: '-73.900709'
23
+ brooklyn:
24
+ :latitude: '40.65'
25
+ :longitude: '-73.95'
26
+ bay ridge:
27
+ :latitude: '40.6261638'
28
+ :longitude: '-74.0329499'
29
+ borough hall:
30
+ :latitude: '40.693219'
31
+ :longitude: '-73.989998'
32
+ brighton beach:
33
+ :latitude: '40.5775751'
34
+ :longitude: '-73.9609634'
35
+ crown heights:
36
+ :latitude: '40.6681032'
37
+ :longitude: '-73.9447994'
38
+ flatbush:
39
+ :latitude: '40.6409217'
40
+ :longitude: '-73.9624327'
41
+ ocean parkway:
42
+ :latitude: '40.6168144'
43
+ :longitude: '-73.9699589'
44
+ park slope:
45
+ :latitude: '40.6681669'
46
+ :longitude: '-73.9800645'
47
+ prospect park:
48
+ :latitude: '40.6617921'
49
+ :longitude: '-73.969555'
50
+ ridgewood:
51
+ :latitude: '40.7108476'
52
+ :longitude: '-73.8977693'
53
+ sheepshead bay:
54
+ :latitude: '40.5975847'
55
+ :longitude: '-73.9536163'
56
+ williamsburg:
57
+ :latitude: '40.7064461'
58
+ :longitude: '-73.9536163'
59
+ manhattan:
60
+ :latitude: '40.7841484'
61
+ :longitude: '-73.9661407'
62
+ battery park city:
63
+ :latitude: '40.7033262'
64
+ :longitude: '-74.0171778'
65
+ beekman:
66
+ :latitude: '40.7108437'
67
+ :longitude: '-74.0056574'
68
+ bowling green:
69
+ :latitude: '40.7052515'
70
+ :longitude: '-74.0127802'
71
+ canal:
72
+ :latitude: '40.733592'
73
+ :longitude: '-73.991404'
74
+ central park:
75
+ :latitude: '40.7769018'
76
+ :longitude: '-73.9754748'
77
+ chelsea:
78
+ :latitude: '40.7497717'
79
+ :longitude: '-73.9976946'
80
+ city hall:
81
+ :latitude: '40.7129755'
82
+ :longitude: '-74.0061418'
83
+ columbus circle:
84
+ :latitude: '40.7680766'
85
+ :longitude: '-73.981909'
86
+ cooper square:
87
+ :latitude: '40.7287973'
88
+ :longitude: '-73.990808'
89
+ cortlandt:
90
+ :latitude: '40.710332'
91
+ :longitude: '-74.011246'
92
+ empire:
93
+ :latitude: '40.7483169'
94
+ :longitude: '-73.9855292'
95
+ fashion:
96
+ :latitude: '40.7513938'
97
+ :longitude: '-73.9905309'
98
+ freedom:
99
+ :latitude: '40.7778625'
100
+ :longitude: '-73.9877754'
101
+ fulton:
102
+ :latitude: '40.710368'
103
+ :longitude: '-74.009509'
104
+ grand central:
105
+ :latitude: '40.752998'
106
+ :longitude: '-73.977056'
107
+ greeley square:
108
+ :latitude: '40.7487038'
109
+ :longitude: '-73.9884031'
110
+ greenwich:
111
+ :latitude: '40.733592'
112
+ :longitude: '-73.991404'
113
+ harlem:
114
+ :latitude: '40.8113824'
115
+ :longitude: '-73.9447994'
116
+ herald square:
117
+ :latitude: '40.7487038'
118
+ :longitude: '-73.9884031'
119
+ hudson:
120
+ :latitude: '41.2125676'
121
+ :longitude: '-73.9477384'
122
+ hunter:
123
+ :latitude: '40.7683607'
124
+ :longitude: '-73.9644531'
125
+ kips bay:
126
+ :latitude: '40.7423292'
127
+ :longitude: '-73.9800645'
128
+ lenox hill:
129
+ :latitude: '40.7645239'
130
+ :longitude: '-73.9624327'
131
+ lincoln square:
132
+ :latitude: '40.773828'
133
+ :longitude: '-73.9844722'
134
+ madison square:
135
+ :latitude: '40.743275'
136
+ :longitude: '-73.988758'
137
+ park place:
138
+ :latitude: '40.713003'
139
+ :longitude: '-74.008324'
140
+ pennsylvania:
141
+ :latitude: '40.755295'
142
+ :longitude: '-73.98175'
143
+ plaza:
144
+ :latitude: '40.759088'
145
+ :longitude: '-73.979543'
146
+ randalls island:
147
+ :latitude: '40.7891291'
148
+ :longitude: '-73.9271644'
149
+ rockefeller center:
150
+ :latitude: '40.7590881'
151
+ :longitude: '-73.9795435'
152
+ roosevelt:
153
+ :latitude: '40.767151'
154
+ :longitude: '-73.967626'
155
+ sheridan square:
156
+ :latitude: '40.7329924'
157
+ :longitude: '-74.0021478'
158
+ sutton:
159
+ :latitude: '40.75802'
160
+ :longitude: '-73.960167'
161
+ times square:
162
+ :latitude: '40.758577'
163
+ :longitude: '-73.984464'
164
+ triboro:
165
+ :latitude: '40.7795849'
166
+ :longitude: '-73.9265846'
167
+ turtle bay:
168
+ :latitude: '40.7540369'
169
+ :longitude: '-73.9668408'
170
+ washington heights:
171
+ :latitude: '40.8401451'
172
+ :longitude: '-73.9389213'
173
+ yorkville:
174
+ :latitude: '40.7762231'
175
+ :longitude: '-73.9492079'
176
+ queens:
177
+ :latitude: '40.7282239'
178
+ :longitude: '-73.7948516'
179
+ borden:
180
+ :latitude: '40.7367709'
181
+ :longitude: '-73.9289394'
182
+ flushing:
183
+ :latitude: '40.7658085'
184
+ :longitude: '-73.8330844'
185
+ jackson heights:
186
+ :latitude: '40.7556818'
187
+ :longitude: '-73.8830701'
188
+ jamaica:
189
+ :latitude: '40.702677'
190
+ :longitude: '-73.7889689'
191
+ long island city:
192
+ :latitude: '40.744679'
193
+ :longitude: '-73.9485424'
194
+ maspeth:
195
+ :latitude: '40.7294018'
196
+ :longitude: '-73.9065883'
197
+ rego park:
198
+ :latitude: '40.7255722'
199
+ :longitude: '-73.8624893'
200
+ richmond hill:
201
+ :latitude: '40.6958108'
202
+ :longitude: '-73.8272029'
203
+ sunnyside:
204
+ :latitude: '40.7432759'
205
+ :longitude: '-73.9196324'
206
+ staten island:
207
+ :latitude: '40.5795317'
208
+ :longitude: '-74.1502007'
209
+ fox hills:
210
+ :latitude: '40.6151042'
211
+ :longitude: '-74.0845858'
212
+ fresh kills:
213
+ :latitude: '40.56417'
214
+ :longitude: '-74.18667'
215
+ wainwright:
216
+ :latitude: '40.552445'
217
+ :longitude: '-74.170149'
218
+ willowbrook:
219
+ :latitude: '40.6031598'
220
+ :longitude: '-74.1384762'
221
+ woodrow:
222
+ :latitude: '40.5394173'
223
+ :longitude: '-74.1915177'
224
+ westchester:
225
+ :latitude: '41.1220194'
226
+ :longitude: '-73.7948516'
227
+ ardsley village:
228
+ :latitude: '41.0106531'
229
+ :longitude: '-73.8437452'
230
+ bedford town:
231
+ :latitude: '41.204262'
232
+ :longitude: '-73.6437397'
233
+ briarcliff manor village:
234
+ :latitude: '41.1402322'
235
+ :longitude: '-73.840231'
236
+ briarcliff ossining:
237
+ :latitude: '41.1765402'
238
+ :longitude: '-73.8400785'
239
+ bronxville village:
240
+ :latitude: '40.9381544'
241
+ :longitude: '-73.8320784'
242
+ buchanan village:
243
+ :latitude: '41.2620383'
244
+ :longitude: '-73.9381943'
245
+ cortlandt town:
246
+ :latitude: '41.2804112'
247
+ :longitude: '-73.8714752'
248
+ croton-on-hudson village:
249
+ :latitude: '41.2084278'
250
+ :longitude: '-73.8912481'
251
+ dobbs ferry village:
252
+ :latitude: '41.0145418'
253
+ :longitude: '-73.872635'
254
+ eastchester town:
255
+ :latitude: '40.9581609'
256
+ :longitude: '-73.807821'
257
+ elmsford village:
258
+ :latitude: '41.0550969'
259
+ :longitude: '-73.8201337'
260
+ greenburgh town:
261
+ :latitude: '41.0452968'
262
+ :longitude: '-73.7902829'
263
+ harrison village:
264
+ :latitude: '40.9689871'
265
+ :longitude: '-73.71263'
266
+ hastings-on-hudson village:
267
+ :latitude: '40.994542'
268
+ :longitude: '-73.8787461'
269
+ irvington village:
270
+ :latitude: '41.0391'
271
+ :longitude: '-73.867'
272
+ larchmont village:
273
+ :latitude: '40.9278769'
274
+ :longitude: '-73.7517983'
275
+ mamaroneck town:
276
+ :latitude: '40.9487097'
277
+ :longitude: '-73.7326309'
278
+ mamaroneck village:
279
+ :latitude: '40.9487097'
280
+ :longitude: '-73.7326309'
281
+ mount kisco (town of bedford):
282
+ :latitude: '41.2042616'
283
+ :longitude: '-73.7270761'
284
+ mount kisco (town of new castle):
285
+ :latitude: '41.2042616'
286
+ :longitude: '-73.7270761'
287
+ mount kisco village:
288
+ :latitude: '41.2042616'
289
+ :longitude: '-73.7270761'
290
+ mount pleasant town:
291
+ :latitude: '41.110493'
292
+ :longitude: '-73.77383'
293
+ mount vernon city:
294
+ :latitude: '40.9125992'
295
+ :longitude: '-73.8370786'
296
+ new castle town:
297
+ :latitude: '41.155377'
298
+ :longitude: '-73.774475'
299
+ new rochelle city:
300
+ :latitude: '40.9114882'
301
+ :longitude: '-73.7823549'
302
+ north castle town:
303
+ :latitude: '40.792028'
304
+ :longitude: '-73.825967'
305
+ north pelham:
306
+ :latitude: '40.714353'
307
+ :longitude: '-74.005973'
308
+ ossining town:
309
+ :latitude: '41.1628731'
310
+ :longitude: '-73.8615246'
311
+ ossining village:
312
+ :latitude: '41.1628731'
313
+ :longitude: '-73.8615246'
314
+ peekskill city:
315
+ :latitude: '41.2900939'
316
+ :longitude: '-73.9204158'
317
+ pelham manor village:
318
+ :latitude: '40.8953773'
319
+ :longitude: '-73.8070778'
320
+ pelham village:
321
+ :latitude: '40.911'
322
+ :longitude: '-73.8083149'
323
+ pleasantville village:
324
+ :latitude: '41.1333371'
325
+ :longitude: '-73.7924152'
326
+ port chester village:
327
+ :latitude: '41.0017643'
328
+ :longitude: '-73.6656834'
329
+ rye brook village:
330
+ :latitude: '41.0192641'
331
+ :longitude: '-73.6834621'
332
+ rye city:
333
+ :latitude: '40.9806535'
334
+ :longitude: '-73.6837399'
335
+ rye town:
336
+ :latitude: '40.9806535'
337
+ :longitude: '-73.6837399'
338
+ scarsdale village:
339
+ :latitude: '41.0050977'
340
+ :longitude: '-73.7845768'
341
+ sleepy hollow:
342
+ :latitude: '41.085652'
343
+ :longitude: '-73.8584684'
344
+ somers town:
345
+ :latitude: '41.327877'
346
+ :longitude: '-73.694823'
347
+ tarrytown village:
348
+ :latitude: '41.0762077'
349
+ :longitude: '-73.8587461'
350
+ tuckahoe village:
351
+ :latitude: '40.9503764'
352
+ :longitude: '-73.827356'
353
+ white plains city:
354
+ :latitude: '41.0339862'
355
+ :longitude: '-73.7629097'
356
+ yonkers city:
357
+ :latitude: '40.9312099'
358
+ :longitude: '-73.8987469'
359
+ yorktown town:
360
+ :latitude: '41.2956496'
361
+ :longitude: '-73.80819'
@@ -1,44 +1,28 @@
1
1
  module Sandy::Provider
2
2
  module ConEd
3
3
  class Report
4
- attr_reader :regions, :neighborhoods
4
+ include Sandy::Provider::StormCenter
5
+ attr_reader :areas
5
6
 
6
7
  def initialize
7
8
  raw_report = JSON.parse(HTTParty.get(coned_url))
8
9
  area_hash = raw_report.fetch("file_data")["curr_custs_aff"]["areas"].first["areas"]
9
- @regions = regions_from_report(area_hash)
10
- @neighborhoods = neighborhoods_from_report(area_hash)
10
+
11
+ @areas = recursive_fetch_areas(
12
+ area_hash,
13
+ ->(area) { area.fetch("areas", nil) }
14
+ )
15
+
11
16
  rescue
12
- raise LoadError, "ConEd reponse was not recognizable."
17
+ raise LoadError, "ConEd response was not recognizable."
13
18
  end
14
19
 
15
- private
16
-
17
- def regions_from_report(areas)
18
- areas.collect do |area|
19
- Sandy::Area.new(area.fetch("custs_out"), area.fetch("area_name"),
20
- { latitude: area["latitude"],
21
- longitude: area["longitude"],
22
- estimated_recovery_time: area["etr"],
23
- total_customers: area["total_custs"] })
24
-
25
- end
20
+ def to_json(*a)
21
+ hash = {}
22
+ { "areas" => @areas.map(&:to_json) }
26
23
  end
27
24
 
28
- def neighborhoods_from_report(areas)
29
- neighborhoods = []
30
- areas.each do |area|
31
- area["areas"].each do |sub_area|
32
- neighborhoods << Sandy::Area.new(sub_area.fetch("custs_out"), sub_area.fetch("area_name"),
33
- { region: area["area_name"],
34
- total_customers: sub_area["total_custs"],
35
- estimated_recovery_time: sub_area["etr"],
36
- latitude: sub_area["latitude"],
37
- longitude: sub_area["longitude"] })
38
- end
39
- end
40
- neighborhoods
41
- end
25
+ private
42
26
 
43
27
  def coned_url
44
28
  base_uri = "http://apps.coned.com"
@@ -47,6 +31,10 @@ module Sandy::Provider
47
31
  directory = response.parsed_response.fetch("root").fetch("directory")
48
32
  "#{base_uri}/stormcenter_external/stormcenter_externaldata/data/interval_generation_data/#{directory}/report.js"
49
33
  end
34
+
35
+ def path
36
+ File.dirname(__FILE__)
37
+ end
50
38
  end
51
39
  end
52
40
  end
@@ -1,3 +1,4 @@
1
+ require "sandy/providers/storm_center"
1
2
  require "sandy/providers/coned/report"
2
3
 
3
4
  module Sandy::Provider
@@ -0,0 +1,14 @@
1
+ module Sandy::Provider
2
+ module CoordinateCache
3
+
4
+ def cached_coordinates_for area_name
5
+ hsh = gps_data.fetch(area_name, {})
6
+ return hsh.fetch(:latitude, nil), hsh.fetch(:longitude, nil)
7
+ end
8
+
9
+ def gps_data
10
+ @gps_data ||= YAML.load(File.open(File.join(path, 'gps_data.yml')))
11
+ end
12
+
13
+ end
14
+ end