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 +47 -2
- data/Rakefile +3 -3
- data/VERSION +1 -1
- data/buoy_data.gemspec +2 -2
- data/lib/buoy_data/buoy.rb +4 -4
- data/lib/buoy_data/noaa_buoy.rb +123 -68
- data/spec/noaa_buoy_spec.rb +17 -9
- metadata +3 -3
data/README.markdown
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
# buoy_data
|
2
2
|
|
3
|
-
|
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(
|
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
|
-
|
14
|
-
|
15
|
-
|
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.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.
|
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-
|
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 = [
|
data/lib/buoy_data/buoy.rb
CHANGED
data/lib/buoy_data/noaa_buoy.rb
CHANGED
@@ -1,70 +1,125 @@
|
|
1
1
|
module BuoyData
|
2
|
-
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
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
|
data/spec/noaa_buoy_spec.rb
CHANGED
@@ -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
|
-
#
|
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
|
-
|
12
|
-
|
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
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
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
|
-
-
|
7
|
+
- 2
|
8
8
|
- 0
|
9
|
-
version: 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-
|
17
|
+
date: 2010-11-22 00:00:00 -05:00
|
18
18
|
default_executable:
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|