adafruit-io 1.0.4 → 2.0.0.beta.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE.md +1 -1
- data/README.md +79 -290
- data/adafruit-io.gemspec +1 -4
- data/lib/adafruit/io.rb +1 -2
- data/lib/adafruit/io/arguments.rb +73 -0
- data/lib/adafruit/io/client.rb +36 -38
- data/lib/adafruit/io/client/data.rb +103 -51
- data/lib/adafruit/io/client/feeds.rb +60 -0
- data/lib/adafruit/io/client/groups.rb +63 -0
- data/lib/adafruit/io/client/tokens.rb +48 -0
- data/lib/adafruit/io/configurable.rb +22 -0
- data/lib/adafruit/io/request_handler.rb +126 -0
- data/lib/adafruit/io/version.rb +1 -1
- metadata +13 -51
- data/lib/adafruit/io/client/feed.rb +0 -55
- data/lib/adafruit/io/client/group.rb +0 -87
- data/lib/adafruit/io/client/io_object.rb +0 -90
- data/lib/adafruit/io/client/request_handler.rb +0 -42
data/adafruit-io.gemspec
CHANGED
@@ -6,7 +6,7 @@ require 'adafruit/io/version'
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "adafruit-io"
|
8
8
|
spec.version = Adafruit::IO::VERSION
|
9
|
-
spec.authors = ["Justin Cooper"]
|
9
|
+
spec.authors = ["Justin Cooper", "Adam Bachman"]
|
10
10
|
spec.email = ["justin@adafruit.com"]
|
11
11
|
spec.summary = %q{Adafruit IO API Client Library}
|
12
12
|
spec.description = %q{API Client Library for the Adafruit IO product}
|
@@ -22,9 +22,6 @@ Gem::Specification.new do |spec|
|
|
22
22
|
|
23
23
|
spec.add_dependency "faraday", "~> 0.8"
|
24
24
|
spec.add_dependency "faraday_middleware", "~> 0.9"
|
25
|
-
spec.add_dependency "activemodel", "~> 4.2"
|
26
|
-
spec.add_dependency "multi_xml", "~> 0.5"
|
27
|
-
spec.add_dependency "addressable", "~> 2.3"
|
28
25
|
|
29
26
|
spec.add_development_dependency "bundler", "~> 1.5"
|
30
27
|
spec.add_development_dependency "rake", "~> 10.4"
|
data/lib/adafruit/io.rb
CHANGED
@@ -0,0 +1,73 @@
|
|
1
|
+
module Adafruit
|
2
|
+
module IO
|
3
|
+
module Arguments
|
4
|
+
|
5
|
+
# Allows us to give a username during client initialization or with a specific method.
|
6
|
+
def extract_username(args)
|
7
|
+
username = @username
|
8
|
+
|
9
|
+
if args.last.is_a?(Hash) && args.last.has_key?(:username)
|
10
|
+
username = args.last.delete(:username)
|
11
|
+
end
|
12
|
+
|
13
|
+
if username.nil?
|
14
|
+
raise "cannot make request when username is nil"
|
15
|
+
end
|
16
|
+
|
17
|
+
[ username, args ]
|
18
|
+
end
|
19
|
+
|
20
|
+
# Allow users to pass a hash with key named 'key' or :key, or just a
|
21
|
+
# plain string to use as a key.
|
22
|
+
#
|
23
|
+
# client.feed({ key: 'myfeed' })
|
24
|
+
# client.feed({ 'key' => 'myfeed' })
|
25
|
+
# client.feed('myfeed')
|
26
|
+
#
|
27
|
+
# Are all equivalent.
|
28
|
+
def get_key_from_arguments(arguments)
|
29
|
+
record_or_key = arguments.shift
|
30
|
+
return nil if record_or_key.nil?
|
31
|
+
|
32
|
+
if record_or_key.is_a?(String)
|
33
|
+
record_or_key
|
34
|
+
elsif record_or_key.is_a?(Hash) && (record_or_key.has_key?('key') || record_or_key.has_key?(:key))
|
35
|
+
record_or_key['key'] || record_or_key[:key]
|
36
|
+
elsif record_or_key.respond_to?(:key)
|
37
|
+
record_or_key.key
|
38
|
+
else
|
39
|
+
raise 'unrecognized object or key value in arguments'
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
# Same as get_key_from_arguments but looking for id
|
44
|
+
def get_id_from_arguments(arguments)
|
45
|
+
record_or_id = arguments.shift
|
46
|
+
return nil if record_or_id.nil?
|
47
|
+
|
48
|
+
if record_or_id.is_a?(String)
|
49
|
+
record_or_id
|
50
|
+
elsif record_or_id.is_a?(Hash) && (record_or_id.has_key?('id') || record_or_id.has_key?(:id))
|
51
|
+
record_or_id['id'] || record_or_id[:id]
|
52
|
+
elsif record_or_id.respond_to?(:id)
|
53
|
+
record_or_id.id
|
54
|
+
else
|
55
|
+
raise 'unrecognized object or id value in arguments'
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
# Get a filtered list of parameters from the next argument
|
60
|
+
def get_query_from_arguments(arguments, params)
|
61
|
+
query = {}
|
62
|
+
options = arguments.shift
|
63
|
+
return query if options.nil?
|
64
|
+
|
65
|
+
params.each do |param|
|
66
|
+
query[param] = options[param.to_sym] if options.has_key?(param.to_sym)
|
67
|
+
end
|
68
|
+
query
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
data/lib/adafruit/io/client.rb
CHANGED
@@ -1,60 +1,55 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'uri'
|
3
|
+
|
1
4
|
require 'faraday'
|
2
5
|
require 'faraday_middleware'
|
3
6
|
require 'faraday_middleware/response/mashify'
|
4
|
-
|
5
|
-
require 'adafruit/io/
|
6
|
-
require 'adafruit/io/
|
7
|
+
|
8
|
+
require 'adafruit/io/arguments'
|
9
|
+
require 'adafruit/io/configurable'
|
10
|
+
require 'adafruit/io/request_handler'
|
11
|
+
|
12
|
+
require 'adafruit/io/client/feeds'
|
7
13
|
require 'adafruit/io/client/data'
|
8
|
-
require 'adafruit/io/client/
|
14
|
+
require 'adafruit/io/client/groups'
|
9
15
|
|
10
16
|
module Adafruit
|
11
17
|
module IO
|
12
18
|
class Client
|
13
19
|
|
14
|
-
include Adafruit::IO::
|
20
|
+
include Adafruit::IO::Arguments
|
21
|
+
include Adafruit::IO::Configurable
|
22
|
+
include Adafruit::IO::RequestHandler
|
15
23
|
|
16
24
|
def initialize(options)
|
17
25
|
@key = options[:key]
|
18
|
-
|
19
|
-
|
20
|
-
def get(url, options = {})
|
21
|
-
request :handle_get, url, options
|
22
|
-
end
|
26
|
+
@username = options[:username]
|
23
27
|
|
24
|
-
|
25
|
-
request :handle_post, url, data, options
|
28
|
+
@debug = !!options[:debug]
|
26
29
|
end
|
27
30
|
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
31
|
+
# Text representation of the client, masking key
|
32
|
+
#
|
33
|
+
# @return [String]
|
34
|
+
def inspect
|
35
|
+
inspected = super
|
36
|
+
inspected = inspected.gsub! @key, "#{@key[0..3]}#{'*' * (@key.size - 3)}" if @key
|
37
|
+
inspected
|
34
38
|
end
|
35
39
|
|
36
40
|
def last_response
|
37
41
|
@last_response
|
38
42
|
end
|
39
43
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
def groups(id_or_key = nil)
|
45
|
-
Adafruit::IO::Group.new(self, id_or_key)
|
46
|
-
end
|
47
|
-
|
48
|
-
def data(feed_id_or_key = nil, id_or_key = nil)
|
49
|
-
Adafruit::IO::Data.new(self, feed_id_or_key, id_or_key)
|
50
|
-
end
|
44
|
+
include Adafruit::IO::Client::Feeds
|
45
|
+
include Adafruit::IO::Client::Data
|
46
|
+
include Adafruit::IO::Client::Groups
|
51
47
|
|
52
|
-
|
48
|
+
private
|
53
49
|
|
54
50
|
def conn
|
55
|
-
|
56
|
-
|
57
|
-
url = ENV['ADAFRUIT_IO_URL']
|
51
|
+
if api_endpoint
|
52
|
+
url = api_endpoint
|
58
53
|
else
|
59
54
|
url = 'https://io.adafruit.com'
|
60
55
|
end
|
@@ -65,17 +60,20 @@ module Adafruit
|
|
65
60
|
c.headers['User-Agent'] = "AdafruitIO-Ruby/#{VERSION} (#{RUBY_PLATFORM})"
|
66
61
|
c.request :json
|
67
62
|
|
68
|
-
|
69
|
-
|
70
|
-
|
63
|
+
# if @debug is true, Faraday will get really noisy when making requests
|
64
|
+
if @debug
|
65
|
+
c.response :logger
|
66
|
+
end
|
71
67
|
|
72
68
|
c.use :instrumentation
|
73
69
|
c.adapter Faraday.default_adapter
|
74
70
|
end
|
75
71
|
end
|
76
72
|
|
77
|
-
def
|
78
|
-
|
73
|
+
def api_url(username, *args)
|
74
|
+
to_join = ['api', 'v2', username].concat(args)
|
75
|
+
|
76
|
+
File.join(*to_join)
|
79
77
|
end
|
80
78
|
end
|
81
79
|
end
|
@@ -1,70 +1,122 @@
|
|
1
|
-
require 'adafruit/io/client/io_object'
|
2
|
-
require 'adafruit/io/client/feed'
|
3
|
-
|
4
1
|
module Adafruit
|
5
2
|
module IO
|
6
|
-
class
|
7
|
-
|
8
|
-
super(client, id_or_key)
|
3
|
+
class Client
|
4
|
+
module Data
|
9
5
|
|
10
|
-
|
11
|
-
|
12
|
-
|
6
|
+
# Add data to a feed.
|
7
|
+
#
|
8
|
+
# Params:
|
9
|
+
# - feed_key: string
|
10
|
+
# - value: string or number
|
11
|
+
# - location (optional): {lat: Number, lon: Number, ele: Number}
|
12
|
+
# - created_at (optional): iso8601 date time string.
|
13
|
+
#
|
14
|
+
def send_data(*args)
|
15
|
+
username, arguments = extract_username(args)
|
16
|
+
feed_key = get_key_from_arguments(arguments)
|
17
|
+
value = arguments.shift
|
13
18
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
19
|
+
attrs = {
|
20
|
+
value: value
|
21
|
+
}
|
22
|
+
|
23
|
+
if arguments.size > 0 && arguments.first.is_a?(Hash)
|
24
|
+
location = arguments.shift
|
25
|
+
if location[:lat] && location[:lon]
|
26
|
+
attrs[:lat] = location[:lat]
|
27
|
+
attrs[:lon] = location[:lon]
|
28
|
+
attrs[:ele] = location[:ele]
|
29
|
+
end
|
30
|
+
end
|
18
31
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
32
|
+
if arguments.size > 0
|
33
|
+
if arguments.first.is_a?(String)
|
34
|
+
created_at = arguments.shift
|
35
|
+
attrs[:created_at] = created_at
|
36
|
+
elsif arguments.first.is_a?(Time)
|
37
|
+
created_at = arguments.shift
|
38
|
+
attrs[:created_at] = created_at.utc.iso8601
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
post api_url(username, 'feeds', feed_key, 'data'), attrs
|
25
43
|
end
|
26
44
|
|
27
|
-
|
28
|
-
|
45
|
+
# Send a batch of data points.
|
46
|
+
#
|
47
|
+
# Points can either be a list of strings, numbers, or hashes with the
|
48
|
+
# keys [ value, created_at OPTIONAL, lat OPTIONAL, lon OPTIONAL, ele OPTIONAL ]
|
49
|
+
#
|
50
|
+
def send_batch_data(*args)
|
51
|
+
username, arguments = extract_username(args)
|
52
|
+
feed_key = get_key_from_arguments(arguments)
|
53
|
+
values = arguments.shift
|
54
|
+
|
55
|
+
if values.nil? || !values.is_a?(Array)
|
56
|
+
raise "expected batch values to be an array"
|
57
|
+
end
|
29
58
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
59
|
+
if !values.first.is_a?(Hash)
|
60
|
+
# convert values to hashes with single key: 'value'
|
61
|
+
values = values.map {|val| {value: val}}
|
62
|
+
end
|
63
|
+
|
64
|
+
post api_url(username, 'feeds', feed_key, 'data', 'batch'), data: values
|
36
65
|
end
|
37
|
-
end
|
38
66
|
|
39
|
-
|
40
|
-
|
41
|
-
|
67
|
+
# Get all data for a feed, may paginate.
|
68
|
+
def data(*args)
|
69
|
+
username, arguments = extract_username(args)
|
70
|
+
feed_key = get_key_from_arguments(arguments)
|
71
|
+
query = get_query_from_arguments arguments, %w(start_time end_time limit)
|
42
72
|
|
43
|
-
|
44
|
-
|
73
|
+
get api_url(username, 'feeds', feed_key, 'data'), query
|
74
|
+
end
|
45
75
|
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
76
|
+
# Get charting data for a feed.
|
77
|
+
def data_chart(*args)
|
78
|
+
username, arguments = extract_username(args)
|
79
|
+
feed_key = get_key_from_arguments(arguments)
|
80
|
+
query = get_query_from_arguments arguments, %w(start_time end_time limit hours resolution)
|
50
81
|
|
51
|
-
|
52
|
-
|
53
|
-
return process_response(response)
|
54
|
-
end
|
82
|
+
get api_url(username, 'feeds', feed_key, 'data', 'chart'), query
|
83
|
+
end
|
55
84
|
|
56
|
-
|
57
|
-
|
58
|
-
|
85
|
+
# Get a single data point.
|
86
|
+
def datum(*args)
|
87
|
+
username, arguments = extract_username(args)
|
88
|
+
feed_key = get_key_from_arguments(arguments)
|
89
|
+
data_id = arguments.shift
|
59
90
|
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
91
|
+
get api_url(username, 'feeds', feed_key, 'data', data_id)
|
92
|
+
end
|
93
|
+
|
94
|
+
# Retrieve the next unprocessed data point.
|
95
|
+
def next_data(*args)
|
96
|
+
username, arguments = extract_username(args)
|
97
|
+
feed_key = get_key_from_arguments(arguments)
|
98
|
+
|
99
|
+
get api_url(username, 'feeds', feed_key, 'data', 'next')
|
100
|
+
end
|
101
|
+
|
102
|
+
# Retrieve the previously processed data point. This method does not
|
103
|
+
# move the stream pointer.
|
104
|
+
def prev_data(*args)
|
105
|
+
username, arguments = extract_username(args)
|
106
|
+
feed_key = get_key_from_arguments(arguments)
|
107
|
+
|
108
|
+
get api_url(username, 'feeds', feed_key, 'data', 'prev')
|
109
|
+
end
|
110
|
+
|
111
|
+
# Move the stream processing pointer to and retrieve the last (newest)
|
112
|
+
# data point available.
|
113
|
+
def last_data(*args)
|
114
|
+
username, arguments = extract_username(args)
|
115
|
+
feed_key = get_key_from_arguments(arguments)
|
116
|
+
|
117
|
+
get api_url(username, 'feeds', feed_key, 'data', 'last')
|
118
|
+
end
|
64
119
|
|
65
|
-
def previous
|
66
|
-
response = @client.get "#{@base_url}/data/previous"
|
67
|
-
return process_response(response)
|
68
120
|
end
|
69
121
|
end
|
70
122
|
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
|
2
|
+
module Adafruit
|
3
|
+
module IO
|
4
|
+
class Client
|
5
|
+
module Feeds
|
6
|
+
|
7
|
+
# Get all feeds.
|
8
|
+
def feeds(*args)
|
9
|
+
username, _ = extract_username(args)
|
10
|
+
|
11
|
+
get api_url(username, 'feeds')
|
12
|
+
end
|
13
|
+
|
14
|
+
# Get a feed specified by key
|
15
|
+
def feed(*args)
|
16
|
+
username, arguments = extract_username(args)
|
17
|
+
feed_key = get_key_from_arguments(arguments)
|
18
|
+
|
19
|
+
get api_url(username, 'feeds', feed_key)
|
20
|
+
end
|
21
|
+
|
22
|
+
# Get a feed along with additional details about the feed. This method
|
23
|
+
# has more to lookup and so is slower than `feed`
|
24
|
+
def feed_details(*args)
|
25
|
+
username, arguments = extract_username(args)
|
26
|
+
feed_key = get_key_from_arguments(arguments)
|
27
|
+
|
28
|
+
get api_url(username, 'feeds', feed_key, 'details')
|
29
|
+
end
|
30
|
+
|
31
|
+
def create_feed(*args)
|
32
|
+
username, arguments = extract_username(args)
|
33
|
+
feed_attrs = arguments.shift
|
34
|
+
|
35
|
+
post api_url(username, 'feeds'), feed_attrs
|
36
|
+
end
|
37
|
+
|
38
|
+
def delete_feed(*args)
|
39
|
+
username, arguments = extract_username(args)
|
40
|
+
feed_key = get_key_from_arguments(arguments)
|
41
|
+
|
42
|
+
delete api_url(username, 'feeds', feed_key)
|
43
|
+
end
|
44
|
+
|
45
|
+
def update_feed(*args)
|
46
|
+
username, arguments = extract_username(args)
|
47
|
+
feed_key = get_key_from_arguments(arguments)
|
48
|
+
query = get_query_from_arguments(
|
49
|
+
arguments,
|
50
|
+
%w(name key description unit_type unit_symbol history visibility
|
51
|
+
license status_notify status_timeout)
|
52
|
+
)
|
53
|
+
|
54
|
+
put api_url(username, 'feeds', feed_key), query
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|