buoy_data 0.1.0 → 0.2.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/README.markdown CHANGED
@@ -1,6 +1,13 @@
1
1
  # buoy_data
2
2
 
3
- The goal of this gem is to provide marine buoy data from a variety of sources.
3
+ ## Description
4
+
5
+ The goal of this gem is to provide a super simple interface to marine buoy data
6
+ from a variety of sources.
7
+
8
+ Currently only [NOAA buoys](http://www.ndbc.noaa.gov/) are supported but adding more is
9
+ planned.
10
+
4
11
 
5
12
  ## Install
6
13
 
@@ -10,13 +17,51 @@ gem install buoy_data
10
17
 
11
18
  ## Usage
12
19
 
20
+ The basic flow is:
21
+
22
+ - instantiate a buoy_data object that will represent the target buoy
23
+ - call its :get method
24
+ - reference the given fields - for the latest reading - via convenient dot notation
25
+
13
26
  <pre>
27
+ require 'rubygems'
14
28
  require 'buoy_data'
15
- noaa_buoy = BuoyData::NoaaBuoy.new(41114)
29
+ noaa_buoy = BuoyData::NoaaBuoy.new(41012) # St Augustine, FL
16
30
  noaa_buoy.get
17
31
  noaa_buoy.WVHT
32
+ => "1.4"
33
+ noaa_buoy.APD
34
+ => "4.6"
35
+ # Wow the swell is pumping, I'm moving ;)!
36
+ </pre>
37
+
38
+ All of the historical data for the given station can be obtained via
39
+ (continuing from the above):
40
+
41
+ <pre>
42
+ noaa_buoy.get_all
18
43
  </pre>
19
44
 
45
+ Which will provide an array of arrays (one array of the fields per row) for all the
46
+ historical data available for the given station. In other words, for the station
47
+ in the example above, 41012, you'd get all the data at:
48
+
49
+ http://www.ndbc.noaa.gov/data/realtime2/41012.spec
50
+
51
+ as an array of arrays.
52
+
53
+ Get a graph of the 5-day trend of Wave Height (WVHT) for the given station (google chart
54
+ api):
55
+
56
+ <pre>
57
+ noaa_buoy.google_chart_url
58
+ </pre>
59
+
60
+ ## TODO
61
+
62
+ - Add friendly / convenient methods for historical station data
63
+ - Webmock for the specs
64
+
20
65
  ## Note on Patches/Pull Requests
21
66
 
22
67
  * Fork the project.
data/Rakefile CHANGED
@@ -10,9 +10,9 @@ begin
10
10
  gem.email = "minch@trazzler.com"
11
11
  gem.homepage = "http://github.com/minch/buoy_data"
12
12
  gem.authors = ["Adam Weller"]
13
- gem.add_development_dependency 'rspec'
14
- gem.add_dependency 'httparty'
15
- gem.files.include 'lib/buoy_data/*.rb'
13
+ gem.add_development_dependency 'rspec'
14
+ gem.add_dependency 'httparty'
15
+ gem.files.include 'lib/buoy_data/*.rb'
16
16
  # gem is a Gem::Specification... see http://www.rubygems.org/read/chapter/20 for additional settings
17
17
  end
18
18
  Jeweler::GemcutterTasks.new
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.0
1
+ 0.2.0
data/buoy_data.gemspec CHANGED
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = %q{buoy_data}
8
- s.version = "0.1.0"
8
+ s.version = "0.2.0"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["Adam Weller"]
12
- s.date = %q{2010-10-26}
12
+ s.date = %q{2010-11-22}
13
13
  s.description = %q{The goal of this gem is to provide marine buoy data from a variety of sources}
14
14
  s.email = %q{minch@trazzler.com}
15
15
  s.extra_rdoc_files = [
@@ -1,7 +1,7 @@
1
1
  module BuoyData
2
- class Buoy
3
- include HTTParty
2
+ class Buoy
3
+ include HTTParty
4
4
 
5
- GET_SUCCESS = 200
6
- end
5
+ GET_SUCCESS = 200
6
+ end
7
7
  end
@@ -1,70 +1,125 @@
1
1
  module BuoyData
2
- class NoaaBuoy < Buoy
3
- format :plain
4
-
5
- attr_accessor :buoy_id, :url, :response
6
-
7
- def initialize(buoy_id)
8
- @url = base_url(buoy_id)
9
- end
10
-
11
- def metaclass
12
- class << self
13
- self
14
- end
15
- end
16
-
17
- def get(raw = false)
18
- response = self.class.get(@url)
19
- return unless response and response.code == GET_SUCCESS
20
- return response if raw
21
-
22
- @response = response
23
- parse_response
24
- end
25
-
26
- def base_url(buoy_id = @buoy_id)
27
- @buoy_id ||= buoy_id
28
-
29
- # The following didn't work as the :description field contains markup we'd have
30
- # to parse
31
- #"http://www.ndbc.noaa.gov/data/latest_obs/#{id}.rss"
32
-
33
- # TODO: get historical data from:
34
- "http://www.ndbc.noaa.gov/data/realtime2/#{buoy_id}.spec"
35
- end
36
-
37
- def self.source
38
- :noaa
39
- end
40
-
41
- def parse_response
42
- # Get all readings
43
- response = @response.parsed_response.split(/\n/)
44
-
45
- # The first line are the fields
46
- fields = response.first.sub(/^#/, '').split
47
-
48
- # The second line are different names of the fields
49
-
50
- # The third line is the most recent reading
51
- response = response[2].split rescue nil
52
- return unless response
53
-
54
- # Set instance vars per field so we can use dot notation to reference each
55
- hash = {}
56
- fields.each_with_index do |field, index|
57
- hash.store(field, response[index])
58
- end
59
-
60
- define_attributes(hash)
61
- end
62
-
63
- def define_attributes(hash)
64
- hash.each_pair { |key, value|
65
- metaclass.send :attr_accessor, key
66
- send "#{key}=".to_sym, value
67
- }
68
- end
69
- end
2
+ class NoaaBuoy < Buoy
3
+ format :plain
4
+
5
+ attr_accessor :buoy_id, :url, :response
6
+
7
+ def initialize(buoy_id, unit_system = self.class.default_unit_system)
8
+ @url = base_url(buoy_id)
9
+ @unit_system = unit_system
10
+ end
11
+
12
+ def metaclass
13
+ class << self
14
+ self
15
+ end
16
+ end
17
+
18
+ def get(raw = false)
19
+ response = self.class.get(@url)
20
+ return unless response and response.code == GET_SUCCESS
21
+ return response if raw
22
+
23
+ @response = response
24
+ parse_response
25
+ end
26
+
27
+ def get_all
28
+ response = get(true)
29
+ return unless response
30
+
31
+ response.parsed_response.split(/\n/)
32
+ end
33
+
34
+ #
35
+ # Get a graph of the historical data for the given buoy.
36
+ #
37
+ # Inspired by:
38
+ #
39
+ # https://github.com/thepug/nbdc_graph/blob/master/generate_graphs.py
40
+ #
41
+ def google_chart_url
42
+ max = 120
43
+ response = get_all
44
+ return unless response
45
+
46
+ historical_data = []
47
+ response.each_with_index do |row, index|
48
+ break if index >= max
49
+ next if row.match(/^#/)
50
+
51
+ row = row.split(/ ?/)
52
+ historical_data << row[5]
53
+ end
54
+ return if historical_data.blank?
55
+ historical_data = historical_data.join(',')
56
+
57
+ [ self.class.google_chart_base(@buoy_id), '&chd=t:', historical_data ].join
58
+ end
59
+
60
+ def base_url(buoy_id = @buoy_id)
61
+ @buoy_id ||= buoy_id
62
+
63
+ # The following didn't work as the :description field contains markup we'd have
64
+ # to parse
65
+ #"http://www.ndbc.noaa.gov/data/latest_obs/#{id}.rss"
66
+ #
67
+ # Could also consider:
68
+ #
69
+ # http://www.ndbc.noaa.gov/data/5day2/41012_5day.txt
70
+ #
71
+ # It has more fields but seems to be an hour hehind the below.
72
+
73
+ "http://www.ndbc.noaa.gov/data/realtime2/#{buoy_id}.spec"
74
+ end
75
+
76
+ def self.source
77
+ :noaa
78
+ end
79
+
80
+ def self.google_chart_base(buoy_id)
81
+ url = [ "http://chart.apis.google.com/chart?cht=lc" ]
82
+ url << "chtt=#{buoy_id}"
83
+ url << "chts=666666,12"
84
+ url << "chco=3366FF"
85
+ url << "chs=250x100"
86
+ url << "chds=0,10"
87
+ url << "chl=WVHT".gsub(/ /, '%20')
88
+ url.join('&')
89
+ end
90
+
91
+
92
+ def self.default_unit_system
93
+ :metric
94
+ end
95
+
96
+ def parse_response
97
+ # Get all readings
98
+ response = @response.parsed_response.split(/\n/)
99
+
100
+ # The first line are the fields
101
+ fields = response.first.sub(/^#/, '').split
102
+
103
+ # The second line are different names of the fields
104
+
105
+ # The third line is the most recent reading
106
+ response = response[2].split rescue nil
107
+ return unless response
108
+
109
+ # Set instance vars per field so we can use dot notation to reference each
110
+ hash = {}
111
+ fields.each_with_index do |field, index|
112
+ hash.store(field, response[index])
113
+ end
114
+
115
+ define_attributes(hash)
116
+ end
117
+
118
+ def define_attributes(hash)
119
+ hash.each_pair { |key, value|
120
+ metaclass.send :attr_accessor, key
121
+ send "#{key}=".to_sym, value
122
+ }
123
+ end
124
+ end
70
125
  end
@@ -2,19 +2,27 @@ require File.join(File.dirname(__FILE__), 'spec_helper')
2
2
 
3
3
  describe BuoyData::NoaaBuoy do
4
4
  before(:each) do
5
- #WebMock.allow_net_connect! # TODO
5
+ #FakeWeb.allow_net_connect = false # TODO
6
6
  @noaa_buoy = BuoyData::NoaaBuoy.new(41114)
7
7
  end
8
-
8
+
9
9
  context 'get' do
10
10
  it 'should get buoy data' do
11
- @noaa_buoy.get
12
- @noaa_buoy.response.code.should == BuoyData::NoaaBuoy::GET_SUCCESS
11
+ @noaa_buoy.get
12
+ @noaa_buoy.response.code.should == BuoyData::NoaaBuoy::GET_SUCCESS
13
+ end
14
+
15
+ it 'should respond to noaa fields' do
16
+ @noaa_buoy.get
17
+ @noaa_buoy.should respond_to :WVHT
13
18
  end
14
19
 
15
- it 'should respond to noaa fields' do
16
- @noaa_buoy.get
17
- @noaa_buoy.should respond_to :WVHT
18
- end
19
- end
20
+ it 'should get all buoy data' do
21
+ @noaa_buoy.get_all.size.should >= 1
22
+ end
23
+
24
+ it 'should get all buoy data' do
25
+ @noaa_buoy.google_chart_url.should match(/chart.apis.google.com/)
26
+ end
27
+ end
20
28
  end
metadata CHANGED
@@ -4,9 +4,9 @@ version: !ruby/object:Gem::Version
4
4
  prerelease: false
5
5
  segments:
6
6
  - 0
7
- - 1
7
+ - 2
8
8
  - 0
9
- version: 0.1.0
9
+ version: 0.2.0
10
10
  platform: ruby
11
11
  authors:
12
12
  - Adam Weller
@@ -14,7 +14,7 @@ autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
16
 
17
- date: 2010-10-26 00:00:00 -04:00
17
+ date: 2010-11-22 00:00:00 -05:00
18
18
  default_executable:
19
19
  dependencies:
20
20
  - !ruby/object:Gem::Dependency