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.
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
@@ -3,6 +3,5 @@ require "adafruit/io/version"
3
3
 
4
4
  module Adafruit
5
5
  module IO
6
-
7
6
  end
8
- end
7
+ end
@@ -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
@@ -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
- require 'json'
5
- require 'adafruit/io/client/feed'
6
- require 'adafruit/io/client/group'
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/request_handler'
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::Client::RequestHandler
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
- end
19
-
20
- def get(url, options = {})
21
- request :handle_get, url, options
22
- end
26
+ @username = options[:username]
23
27
 
24
- def post(url, data, options = {})
25
- request :handle_post, url, data, options
28
+ @debug = !!options[:debug]
26
29
  end
27
30
 
28
- def put(url, data, options = {})
29
- request :handle_put, url, data, options
30
- end
31
-
32
- def delete(url, options = {})
33
- request :handle_delete, url
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
- def feeds(id_or_key = nil)
41
- Adafruit::IO::Feed.new(self, id_or_key)
42
- end
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
- private
48
+ private
53
49
 
54
50
  def conn
55
- #Faraday.new(:url => 'http://localhost:3002') do |c|
56
- if ENV['ADAFRUIT_IO_URL']
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
- c.response :xml, :content_type => /\bxml$/
69
- #c.response :mashify, :content_type => /\bjson$/
70
- #c.response :json
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 request(method, url, data = nil, options = nil)
78
- @last_response = send(method, url, data)
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 Data < IOObject
7
- def initialize(client = nil, feed = nil, id_or_key = nil)
8
- super(client, id_or_key)
3
+ class Client
4
+ module Data
9
5
 
10
- @feed = feed
11
- @base_url = "feeds/#{@feed.id}"
12
- end
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
- def create(options = {})
15
- response = @client.post "#{@base_url}/data", options
16
- return process_response(response)
17
- end
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
- def retrieve(id_or_key = nil, options = {})
20
- if id_or_key
21
- @id_or_key = id_or_key
22
- response = @client.get "#{@base_url}/data/#{id_or_key}", options
23
- else
24
- response = @client.get "#{@base_url}/data", options
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
- return process_response(response)
28
- end
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
- def delete
31
- response = @client.delete "#{@base_url}/data/#{self.id}"
32
- if response == 200
33
- {"delete" => true, "id" => self.id}
34
- else
35
- {"delete" => false, "id" => self.id}
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
- def save
40
- response = @client.put "#{@base_url}/data/#{self.id}", serialize_params(self)
41
- @unsaved_values.clear
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
- return process_response(response)
44
- end
73
+ get api_url(username, 'feeds', feed_key, 'data'), query
74
+ end
45
75
 
46
- def send_data(data)
47
- response = @client.post "#{@base_url}/data/send", {:value => data}
48
- return process_response(response)
49
- end
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
- def receive
52
- response = @client.get "#{@base_url}/data/last"
53
- return process_response(response)
54
- end
82
+ get api_url(username, 'feeds', feed_key, 'data', 'chart'), query
83
+ end
55
84
 
56
- def last
57
- receive
58
- end
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
- def next
61
- response = @client.get "#{@base_url}/data/next"
62
- return process_response(response)
63
- end
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