m2x 1.0.0 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 5ec355421314977e15e2c05ae0eb1efc9d0177d4
4
- data.tar.gz: ed401f222ce4c00a41e2d347a1fcafb268a2d433
3
+ metadata.gz: 084cf856cdc4b7844875f78adb56260dc52257a0
4
+ data.tar.gz: b9cc0d3d5185bc385d37121fa183248ceaef97f4
5
5
  SHA512:
6
- metadata.gz: f1e7b7bac788b62e4868e16073d048bb104e64984c1fbe08df3d1e47fccd2b01482a10f67b096b7dacfa9e37644a6031ec3d1750af88eda41e61d273d5289815
7
- data.tar.gz: cdde61bc4b9f577c5d9bbaf85f6ebfd079f158c3bbbc75e8caeb9305837d536d4e9ada1715100332d59dcafd87ca8e59c82f7cd90bebd20d7e3f40f1c521c658
6
+ metadata.gz: 33ee0afd354825adbe05a148c191776e07dd1ac3c3d41fb220d90fc1eee6f7d8040baa5f3cee0106fdb5961e977a149d5ae14600a8db5196552045cef03a898d
7
+ data.tar.gz: 1f12c23f3fe2aea2ccf4ccb93797c4be1a7b08b6fe336ba7a157b1c92a45d0db98d5007cd1ff3da17f527e10412388dffd54b6626048e421d0b9d99754c22fd1
data/README.md CHANGED
@@ -9,7 +9,7 @@ Getting Started
9
9
  ==========================
10
10
  1. Signup for an [M2X Account](https://m2x.att.com/signup).
11
11
  2. Obtain your _Master Key_ from the Master Keys tab of your [Account Settings](https://m2x.att.com/account) screen.
12
- 2. Create your first [Data Source Blueprint](https://m2x.att.com/blueprints) and copy its _Feed ID_.
12
+ 2. Create your first [Device](https://m2x.att.com/devices) and copy its _Device ID_.
13
13
  3. Review the [M2X API Documentation](https://m2x.att.com/developer/documentation/overview).
14
14
 
15
15
  ## Installation
@@ -20,43 +20,46 @@ $ gem install m2x
20
20
 
21
21
  ## Usage
22
22
 
23
- In order to communicate with the M2X API, you need an instance of [M2X](lib/m2x.rb). You need to pass your API key in the constructor to access your data.
23
+ In order to communicate with the M2X API, you need an instance of [M2X::Client](lib/m2x/client.rb). You need to pass your API key in the constructor to access your data.
24
24
 
25
25
  ```ruby
26
- m2x = M2X.new(<YOUR-API-KEY>)
26
+ m2x = M2X::Client.new(<YOUR-API-KEY>)
27
27
  ```
28
28
 
29
29
  This provides an interface to your data on M2X
30
30
 
31
- - [Blueprints](lib/m2x/blueprints.rb)
31
+ - [Distribution](lib/m2x/distribution.rb)
32
32
  ```ruby
33
- blueprints_api = m2x.blueprints
34
- ```
33
+ distribution = m2x.distribution("<DISTRIBUTION-ID>")
35
34
 
36
- - [Batches](lib/m2x/batches.rb)
37
- ```ruby
38
- batches_api = m2x.batches
39
- ```
40
- - [Datasources](lib/m2x/datasources.rb)
41
- ```ruby
42
- datasources_api = m2x.datasources
35
+ distributions = m2x.distributions
43
36
  ```
44
37
 
45
- - [Feeds](lib/m2x/feeds.rb)
38
+ - [Device](lib/m2x/device.rb)
46
39
  ```ruby
47
- feeds_api = m2x.feeds
40
+ device = m2x.device("<DEVICE-ID>")
41
+
42
+ devices = m2x.devices
48
43
  ```
49
44
 
50
- - [Keys](lib/m2x/keys.rb)
45
+ - [Key](lib/m2x/key.rb)
51
46
  ```ruby
52
- keys_api = m2x.keys
47
+ key = m2x.key("<KEY-TOKEN>")
48
+
49
+ keys = m2x.keys
53
50
  ```
54
51
 
55
52
  Refer to the documentation on each class for further usage instructions.
56
53
 
57
54
  ## Example
58
55
 
59
- In order to run this example, you will need a `Feed ID` and `API Key`. If you don't have any, access your M2X account, create a new [Data Source Blueprint](https://m2x.att.com/blueprints), and copy the `Feed ID` and `API Key` values. The following script will send your CPU load average to three different streams named `load_1m`, `load_5m` and `load_15`. Check that there's no need to create a stream in order to write values into it:
56
+ In order to run this example, you will need a `Device ID` and `API Key`. If you don't have any, access your M2X account, create a new [Device](https://m2x.att.com/devices), and copy the `Device ID` and `API Key` values. The following script will send your CPU load average to three different streams named `load_1m`, `load_5m` and `load_15`. Check that there's no need to create a stream in order to write values into it.
57
+
58
+ In order to execute this script run:
59
+
60
+ ```bash
61
+ API_KEY=<YOUR-API-KEY> DEVICE=<YOUR-DEVICE-ID> ./m2x-uptime.rb
62
+ ```
60
63
 
61
64
  ```ruby
62
65
  #! /usr/bin/env ruby
@@ -69,13 +72,17 @@ In order to run this example, you will need a `Feed ID` and `API Key`. If you do
69
72
  require "time"
70
73
  require "m2x"
71
74
 
72
- API_KEY = "<YOUR-FEED-API-KEY>"
73
- FEED = "<YOUR-FEED-ID>"
75
+ API_KEY = ENV.fetch("API_KEY")
76
+ DEVICE = ENV.fetch("DEVICE")
74
77
 
75
- m2x = M2X.new(API_KEY)
78
+ puts "M2X::Client/#{M2X::Client::VERSION} example"
76
79
 
77
80
  @run = true
78
- trap(:INT) { @run = false }
81
+
82
+ stop = Proc.new { @run = false }
83
+
84
+ trap(:INT, &stop)
85
+ trap(:TERM, &stop)
79
86
 
80
87
  # Match `uptime` load averages output for both Linux and OSX
81
88
  UPTIME_RE = /(\d+\.\d+),? (\d+\.\d+),? (\d+\.\d+)$/
@@ -84,10 +91,15 @@ def load_avg
84
91
  `uptime`.match(UPTIME_RE).captures
85
92
  end
86
93
 
94
+ m2x = M2X::Client.new(API_KEY)
95
+
96
+ # Get the device
97
+ device = m2x.device(DEVICE)
98
+
87
99
  # Create the streams if they don't exist
88
- m2x.feeds.update_stream(FEED, "load_1m")
89
- m2x.feeds.update_stream(FEED, "load_5m")
90
- m2x.feeds.update_stream(FEED, "load_15m")
100
+ device.create_stream("load_1m")
101
+ device.create_stream("load_5m")
102
+ device.create_stream("load_15m")
91
103
 
92
104
  while @run
93
105
  load_1m, load_5m, load_15m = load_avg
@@ -96,14 +108,14 @@ while @run
96
108
  now = Time.now.iso8601
97
109
 
98
110
  values = {
99
- load_1m: [ { value: load_1m, at: now } ],
100
- load_5m: [ { value: load_5m, at: now } ],
101
- load_15m: [ { value: load_15m, at: now } ]
111
+ load_1m: [ { value: load_1m, timestamp: now } ],
112
+ load_5m: [ { value: load_5m, timestamp: now } ],
113
+ load_15m: [ { value: load_15m, timestamp: now } ]
102
114
  }
103
115
 
104
- res = m2x.feeds.post_multiple(FEED, values)
116
+ res = device.post_updates(values: values)
105
117
 
106
- abort res.json["message"] unless res.code == 202
118
+ abort res.json["message"] unless res.success?
107
119
 
108
120
  sleep 1
109
121
  end
data/lib/m2x/client.rb CHANGED
@@ -2,94 +2,180 @@ require "net/http"
2
2
  require "json"
3
3
  require "openssl"
4
4
 
5
- class M2X
6
- class Client
7
- API_BASE = "http://api-m2x.att.com/v1".freeze
5
+ # Interface for connecting with M2X API service.
6
+ #
7
+ # This class provides convenience methods to access M2X most common resources.
8
+ # It can also be used to access any endpoint directly like this:
9
+ #
10
+ # m2x = M2X::Client.new("<YOUR-API-KEY>")
11
+ # m2x.get("/some_path")
12
+ #
13
+ class M2X::Client
14
+ DEFAULT_API_BASE = "https://api-m2x.att.com".freeze
15
+ DEFAULT_API_VERSION = "v2".freeze
16
+
17
+ CA_FILE = File.expand_path("../cacert.pem", __FILE__)
18
+
19
+ USER_AGENT = "M2X-Ruby/#{M2X::Client::VERSION} #{RUBY_ENGINE}/#{RUBY_VERSION} (#{RUBY_PLATFORM})".freeze
20
+
21
+ attr_accessor :api_key
22
+ attr_accessor :api_base
23
+ attr_accessor :api_version
24
+ attr_reader :last_response
25
+
26
+ def initialize(api_key=nil, api_base=nil)
27
+ @api_key = api_key
28
+ @api_base = api_base
29
+ @api_version = api_version
30
+ end
8
31
 
9
- CA_FILE = File.expand_path("../cacert.pem", __FILE__)
32
+ # Returns the status of the M2X system.
33
+ #
34
+ # The response to this endpoint is an object in which each of its attributes
35
+ # represents an M2X subsystem and its current status.
36
+ def status
37
+ get("/status")
38
+ end
10
39
 
11
- USER_AGENT = "M2X/#{::M2X::VERSION} (Ruby Net::HTTP)".freeze
40
+ # Obtain a Device from M2X
41
+ #
42
+ # This method instantiates an instance of Device and calls `Device#view`
43
+ # method, returning the device instance with all its attributes initialized
44
+ def device(id)
45
+ M2X::Client::Device.new(self, "id" => id).tap(&:view)
46
+ end
12
47
 
13
- def initialize(api_key=nil, api_base=nil)
14
- @api_base = api_base
15
- @api_key = api_key
16
- end
48
+ # Creates a new device on M2X with the specified parameters
49
+ def create_device(params)
50
+ M2X::Client::Device.create!(self, params)
51
+ end
17
52
 
18
- def request(verb, path, qs=nil, params=nil, headers=nil)
19
- url = URI.parse(File.join(api_base, path))
53
+ # Retrieve the list of devices accessible by the authenticated API key that
54
+ # meet the search criteria.
55
+ #
56
+ # See M2X::Client::Device.list for more details
57
+ def devices(params={})
58
+ M2X::Client::Device.list(self, params)
59
+ end
20
60
 
21
- url.query = URI.encode_www_form(qs) unless qs.nil? || qs.empty?
61
+ # Search the catalog of public Devices.
62
+ #
63
+ # This allows unauthenticated users to search Devices from other users that
64
+ # have been marked as public, allowing them to read public Device metadata,
65
+ # locations, streams list, and view each Devices' stream metadata and its
66
+ # values.
67
+ #
68
+ # See M2X::Client::Device.catalog for more details
69
+ def device_catalog(params={})
70
+ M2X::Client::Device.catalog(self, params)
71
+ end
22
72
 
23
- headers = default_headers.merge(headers || {})
73
+ # Obtain a Distribution from M2X
74
+ #
75
+ # This method instantiates an instance of Distribution and calls
76
+ # `Distribution#view` method, returning the device instance with all
77
+ # its attributes initialized
78
+ def distribution(id)
79
+ M2X::Client::Distribution.new(self, "id" => id).tap(&:view)
80
+ end
24
81
 
25
- body = if params
26
- headers["Content-Type"] ||= "application/x-www-form-urlencoded"
82
+ # Creates a new device distribution on M2X with the specified parameters
83
+ def create_distribution(params)
84
+ M2X::Client::Distribution.create!(self, params)
85
+ end
27
86
 
28
- case headers["Content-Type"]
29
- when "application/json" then JSON.dump(params)
30
- when "application/x-www-form-urlencoded" then URI.encode_www_form(params)
31
- else
32
- raise ArgumentError, "Unrecognized Content-Type `#{headers["Content-Type"]}`"
33
- end
34
- end
87
+ # Retrieve list of device distributions accessible by the authenticated
88
+ # API key.
89
+ #
90
+ # See M2X::Client::Distribution.list for more details
91
+ def distributions(params={})
92
+ M2X::Client::Distribution.list(self, params)
93
+ end
35
94
 
36
- options = {}
37
- options.merge!(use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER, ca_file: CA_FILE) if url.scheme == "https"
95
+ # Obtain an API Key from M2X
96
+ #
97
+ # This method instantiates an instance of Key and calls
98
+ # `Key#view` method, returning the key instance with all
99
+ # its attributes initialized
100
+ def key(key)
101
+ M2X::Client::Key.new(self, "key" => key).tap(&:view)
102
+ end
38
103
 
39
- path = url.path
40
- path << "?#{url.query}" if url.query
104
+ # Create a new API Key
105
+ #
106
+ # Note that, according to the parameters sent, you can create a
107
+ # Master API Key or a Device/Stream API Key.
108
+ #
109
+ # See M2X::Client::Key.create! for more details
110
+ def create_key(params)
111
+ M2X::Client::Key.create!(self, params)
112
+ end
41
113
 
42
- res = Net::HTTP.start(url.host, url.port, options) do |http|
43
- http.send_request(verb.to_s.upcase, path, body, headers)
44
- end
114
+ # Retrieve list of keys associated with the user account.
115
+ #
116
+ # See M2X::Client::Key.list for more details
117
+ def keys
118
+ M2X::Client::Key.list(self)
119
+ end
45
120
 
46
- Response.new(res)
121
+ # Define methods for accessing M2X REST API
122
+ [:get, :post, :put, :delete, :head, :options, :patch].each do |verb|
123
+ define_method verb do |path, qs=nil, params=nil, headers=nil|
124
+ request(verb, path, qs, params, headers)
47
125
  end
126
+ end
48
127
 
49
- [:get, :post, :put, :delete, :head, :options, :patch].each do |verb|
50
- define_method verb do |path, qs=nil, params=nil, headers=nil|
51
- request(verb, path, qs, params, headers)
52
- end
53
- end
128
+ private
129
+ def request(verb, path, qs=nil, params=nil, headers=nil)
130
+ url = URI.parse(File.join(api_base, versioned(path)))
54
131
 
55
- class Response
56
- attr_reader :response
132
+ url.query = URI.encode_www_form(qs) unless qs.nil? || qs.empty?
57
133
 
58
- def initialize(response)
59
- @response = response
60
- end
134
+ headers = default_headers.merge(headers || {})
61
135
 
62
- def raw
63
- @response.body
64
- end
136
+ body = if params
137
+ headers["Content-Type"] ||= "application/x-www-form-urlencoded"
65
138
 
66
- def json
67
- raise "#{@response.content_type} is not application/json" unless @response.content_type == "application/json"
139
+ case headers["Content-Type"]
140
+ when "application/json" then JSON.dump(params)
141
+ when "application/x-www-form-urlencoded" then URI.encode_www_form(params)
142
+ else
143
+ raise ArgumentError, "Unrecognized Content-Type `#{headers["Content-Type"]}`"
144
+ end
145
+ end
68
146
 
69
- @json ||= ::JSON.parse(raw)
70
- end
147
+ options = {}
148
+ options.merge!(use_ssl: true, verify_mode: OpenSSL::SSL::VERIFY_PEER, ca_file: CA_FILE) if url.scheme == "https"
71
149
 
72
- def code
73
- @code ||= @response.code.to_i
74
- end
150
+ path = url.path
151
+ path << "?#{url.query}" if url.query
75
152
 
76
- def headers
77
- @headers ||= @response.to_hash
78
- end
153
+ res = Net::HTTP.start(url.host, url.port, options) do |http|
154
+ http.send_request(verb.to_s.upcase, path, body, headers)
79
155
  end
80
156
 
81
- private
157
+ @last_response = Response.new(res)
158
+ end
82
159
 
83
- def api_base
84
- @api_base ||= API_BASE
85
- end
160
+ def api_base
161
+ @api_base ||= DEFAULT_API_BASE
162
+ end
86
163
 
87
- def default_headers
88
- @headers ||= begin
89
- headers = { "User-Agent" => USER_AGENT }
90
- headers.merge!("X-M2X-KEY" => @api_key) if @api_key
91
- headers
92
- end
93
- end
164
+ def api_version
165
+ @api_version ||= DEFAULT_API_VERSION
166
+ end
167
+
168
+ def versioned(path)
169
+ versioned?(path) ? path : "/#{api_version}#{path}"
170
+ end
171
+
172
+ def versioned?(path)
173
+ path =~ /^\/v\d+\//
174
+ end
175
+
176
+ def default_headers
177
+ @headers ||= { "User-Agent" => USER_AGENT }.tap do |headers|
178
+ headers["X-M2X-KEY"] = @api_key if @api_key
179
+ end
94
180
  end
95
181
  end
data/lib/m2x/device.rb ADDED
@@ -0,0 +1,147 @@
1
+ # Wrapper for AT&T M2X Device API
2
+ # https://m2x.att.com/developer/documentation/v2/device
3
+ class M2X::Client::Device < M2X::Client::Resource
4
+
5
+ PATH = "/devices"
6
+
7
+ class << self
8
+ # Retrieve the list of devices accessible by the authenticated API key that
9
+ # meet the search criteria.
10
+ #
11
+ # https://m2x.att.com/developer/documentation/v2/device#List-Search-Devices
12
+ def list(client, params={})
13
+ res = client.get(PATH, params)
14
+
15
+ res.json["devices"].map{ |atts| new(client, atts) } if res.success?
16
+ end
17
+
18
+ # Search the catalog of public Devices.
19
+ #
20
+ # This allows unauthenticated users to search Devices from other users
21
+ # that have been marked as public, allowing them to read public Device
22
+ # metadata, locations, streams list, and view each Devices' stream metadata
23
+ # and its values.
24
+ #
25
+ # https://m2x.att.com/developer/documentation/v2/device#List-Search-Public-Devices-Catalog
26
+ def catalog(client, params={})
27
+ res = client.get("#{PATH}/catalog", params)
28
+
29
+ res.json["devices"].map{ |atts| new(client, atts) } if res.success?
30
+ end
31
+
32
+ # List Device Groups
33
+ # Retrieve the list of device groups for the authenticated user.
34
+ #
35
+ # https://m2x.att.com/developer/documentation/v2/device#List-Device-Groups
36
+ def groups(client)
37
+ client.get("#{PATH}/groups")
38
+ end
39
+
40
+ # Create a new device
41
+ #
42
+ # https://m2x.att.com/developer/documentation/v2/device#Create-Device
43
+ def create!(client, params)
44
+ res = client.post(PATH, nil, params, "Content-Type" => "application/json")
45
+
46
+ new(client, res.json) if res.success?
47
+ end
48
+ end
49
+
50
+ def path
51
+ @path ||= "#{ PATH }/#{ URI.encode(@attributes.fetch("id")) }"
52
+ end
53
+
54
+ # View Request Log
55
+ # Retrieve list of HTTP requests received lately by the specified device
56
+ # (up to 100 entries).
57
+ #
58
+ # https://m2x.att.com/developer/documentation/v2/device#View-Request-Log
59
+ def log
60
+ @client.get("#{path}/log")
61
+ end
62
+
63
+ # Get location details of an existing Device.
64
+ #
65
+ # Note that this method can return an empty value (response status
66
+ # of 204) if the device has no location defined.
67
+ #
68
+ # https://m2x.att.com/developer/documentation/v2/device#Read-Device-Location
69
+ def location
70
+ @client.get("#{path}/location")
71
+ end
72
+
73
+ # Update the current location of the specified device.
74
+ #
75
+ # https://m2x.att.com/developer/documentation/v2/device#Update-Device-Location
76
+ def update_location(params)
77
+ @client.put("#{path}/location", nil, params, "Content-Type" => "application/json")
78
+ end
79
+
80
+ # Post Device Updates (Multiple Values to Multiple Streams)
81
+ #
82
+ # This method allows posting multiple values to multiple streams
83
+ # belonging to a device and optionally, the device location.
84
+ #
85
+ # All the streams should be created before posting values using this method.
86
+ #
87
+ # The `values` parameter contains an object with one attribute per each stream to be updated.
88
+ # The value of each one of these attributes is an array of timestamped values.
89
+ #
90
+ # {
91
+ # temperature: [
92
+ # { "timestamp": <Time in ISO8601>, "value": x },
93
+ # { "timestamp": <Time in ISO8601>, "value": y },
94
+ # ],
95
+ # humidity: [
96
+ # { "timestamp": <Time in ISO8601>, "value": x },
97
+ # { "timestamp": <Time in ISO8601>, "value": y },
98
+ # ]
99
+ #
100
+ # }
101
+ #
102
+ # The optional location attribute can contain location information that will
103
+ # be used to update the current location of the specified device
104
+ #
105
+ # https://staging.m2x.sl.attcompute.com/developer/documentation/v2/device#Post-Device-Updates--Multiple-Values-to-Multiple-Streams-
106
+ def post_updates(params)
107
+ @client.post("#{path}/updates", nil, params, "Content-Type" => "application/json")
108
+ end
109
+
110
+ # Retrieve list of data streams associated with the device.
111
+ #
112
+ # https://m2x.att.com/developer/documentation/v2/device#List-Data-Streams
113
+ def streams
114
+ ::M2X::Client::Stream.list(@client, self)
115
+ end
116
+
117
+ # Get details of a specific data Stream associated with the device
118
+ #
119
+ # https://m2x.att.com/developer/documentation/v2/device#View-Data-Stream
120
+ def stream(name)
121
+ ::M2X::Client::Stream.fetch(@client, self, name)
122
+ end
123
+
124
+ # Update a data stream associated with the Device
125
+ # (if a stream with this name does not exist it gets created).
126
+ #
127
+ # https://m2x.att.com/developer/documentation/v2/device#Create-Update-Data-Stream
128
+ def update_stream(name, params={})
129
+ stream = ::M2X::Client::Stream.new(@client, self, "name" => name)
130
+
131
+ stream.update!(params)
132
+ end
133
+ alias_method :create_stream, :update_stream
134
+
135
+ # Returns a list of API keys associated with the device
136
+ def keys
137
+ ::M2X::Client::Key.list(@client, params.merge(device: self["id"]))
138
+ end
139
+
140
+ # Creates a new API key associated to the device
141
+ #
142
+ # If a parameter named `stream` is supplied with a stream name, it
143
+ # will create an API key associated with that stream only.
144
+ def create_key(params)
145
+ ::M2X::Client::Key.create!(@client, params.merge(device: self["id"]))
146
+ end
147
+ end
@@ -0,0 +1,53 @@
1
+ # Wrapper for AT&T M2X Distribution API
2
+ # https://m2x.att.com/developer/documentation/v2/distribution
3
+ class M2X::Client::Distribution < M2X::Client::Resource
4
+
5
+ PATH = "/distributions"
6
+
7
+ class << self
8
+ # Retrieve list of device distributions accessible by the authenticated
9
+ # API key.
10
+ #
11
+ # https://m2x.att.com/developer/documentation/v2/distribution#List-Distributions
12
+ def list(client, params={})
13
+ res = client.get(PATH, params)
14
+
15
+ res.json["distributions"].map{ |atts| new(client, atts) } if res.success?
16
+ end
17
+ alias_method :search, :list
18
+
19
+ # Create a new device distribution
20
+ #
21
+ # https://m2x.att.com/developer/documentation/v2/distribution#Create-Distribution
22
+ def create!(client, params)
23
+ res = client.post(PATH, nil, params, "Content-Type" => "application/json")
24
+
25
+ new(client, res.json) if res.success?
26
+ end
27
+ end
28
+
29
+ def path
30
+ @path ||= "#{ PATH }/#{ URI.encode(@attributes.fetch("id")) }"
31
+ end
32
+
33
+ # Retrieve list of devices added to the specified distribution.
34
+ #
35
+ # https://m2x.att.com/developer/documentation/v2/distribution#List-Devices-from-an-existing-Distribution
36
+ def devices(params={})
37
+ res = @client.get("#{path}/devices", params)
38
+
39
+ res.json["devices"].map{ |atts| ::M2X::Client::Device.new(@client, atts) } if res.success?
40
+ end
41
+
42
+ # Add a new device to an existing distribution
43
+ #
44
+ # Accepts a `serial` parameter, that must be a unique identifier
45
+ # within this distribution.
46
+ #
47
+ # https://m2x.att.com/developer/documentation/v2/distribution#Add-Device-to-an-existing-Distribution
48
+ def add_device(serial)
49
+ res = @client.post("#{path}/devices", nil, { serial: serial }, "Content-Type" => "application/json")
50
+
51
+ ::M2X::Client::Device.new(@client, res.json) if res.success?
52
+ end
53
+ end
data/lib/m2x/key.rb ADDED
@@ -0,0 +1,49 @@
1
+ # Wrapper for AT&T M2X Keys API
2
+ # https://m2x.att.com/developer/documentation/v2/keys
3
+ class M2X::Client::Key < M2X::Client::Resource
4
+
5
+ PATH = "/keys"
6
+
7
+ class << self
8
+ # Retrieve list of keys associated with the user account.
9
+ #
10
+ # https://m2x.att.com/developer/documentation/v2/keys#List-Keys
11
+ def list(client, params={})
12
+ res = client.get(PATH, params)
13
+
14
+ res.json["keys"].map{ |atts| new(client, atts) } if res.success?
15
+ end
16
+
17
+ # Create a new API Key
18
+ #
19
+ # Note that, according to the parameters sent, you can create a
20
+ # Master API Key or a Device/Stream API Key.
21
+ #
22
+ # https://m2x.att.com/developer/documentation/v2/keys#Create-Key
23
+ def create!(client, params={})
24
+ res = client.post(PATH, nil, params, "Content-Type" => "application/json")
25
+
26
+ new(client, res.json) if res.success?
27
+ end
28
+ end
29
+
30
+ def path
31
+ @path ||= "#{ PATH }/#{ URI.encode(@attributes.fetch("key")) }"
32
+ end
33
+
34
+ # Regenerate an API Key token
35
+ #
36
+ # Note that if you regenerate the key that you're using for
37
+ # authentication then you would need to change your scripts to
38
+ # start using the new key token for all subsequent requests.
39
+ #
40
+ # https://m2x.att.com/developer/documentation/v2/keys#Regenerate-Key
41
+ def regenerate
42
+ res = @client.post("#{path}/regenerate", nil, {})
43
+
44
+ if res.success?
45
+ @path = nil
46
+ @attributes = res.json
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,40 @@
1
+ require "forwardable"
2
+
3
+ # Wrapper for M2X::Client resources
4
+ class M2X::Client::Resource
5
+ extend Forwardable
6
+
7
+ attr_reader :attributes
8
+
9
+ def_delegator :@attributes, :[]
10
+
11
+ def initialize(client, attributes)
12
+ @client = client
13
+ @attributes = attributes
14
+ end
15
+
16
+ # Return the resource details
17
+ def view
18
+ res = @client.get(path)
19
+
20
+ @attributes = res.json if res.success?
21
+ end
22
+
23
+ # Update an existing resource details
24
+ def update!(params)
25
+ @client.put(path, nil, params, "Content-Type" => "application/json")
26
+ end
27
+
28
+ # Delete the resource
29
+ def delete!
30
+ @client.delete(path)
31
+ end
32
+
33
+ def inspect
34
+ "<#{self.class.name}: #{attributes.inspect}>"
35
+ end
36
+
37
+ def path
38
+ raise NotImplementedError
39
+ end
40
+ end