particlerb 0.0.2 → 0.0.3

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: 3df82a4b9e831fa635c52d24e9d0f59bd3b6209d
4
- data.tar.gz: 61c6aa2eba790faeee99e4cde8ea6f04e214946b
3
+ metadata.gz: 69be1802b2959a94182268ee4dc69983a7675941
4
+ data.tar.gz: 42eed9eebd4ff5fb83ae18a4404886d31ecee5c8
5
5
  SHA512:
6
- metadata.gz: 4a4f275a4d1b7b1dde368e620a76205e4ee34fd23aaca4682d3df0bee6c3407786504d05b648cfe56ddb8ea0e88404a69d5a3479705e58ee6e9eb2276cb5f1d5
7
- data.tar.gz: 95e421509a8109498915efcb25096969204afb0fb673a38edca51957ea20874d784a9dca23383e5d6cce600bb65e429f0ad7b8048b8de06985eb09b7c8d6d32f
6
+ metadata.gz: 4528fb9da088fe67f1f37c289d8db4bf0db14f12a78fd6f8701ec6298f45c5a4c9559358bd41db8271df389578d59037cbd469f0a7f1c845dfd3313d4842a298
7
+ data.tar.gz: b5225ac476ba0624c25cce31f980edc6d4542b105c92f5f766a86159e79ee3dcefc357ebb16288b81de0f2a4a374d05da31ebcec38f37754cf689e1a31174440
data/README.md CHANGED
@@ -12,13 +12,16 @@ Ruby client for the [Particle.io] Cloud API with an object-oriented interface
12
12
 
13
13
  ## Installation
14
14
 
15
- Install via Rubygems
16
-
17
- gem install particlerb
15
+ ```
16
+ # Install via Rubygems
17
+ $ gem install particlerb
18
18
 
19
- ... or add to your Gemfile
19
+ # or add to your Gemfile
20
+ gem "particlerb", "~> 0.0.3"
20
21
 
21
- gem "particlerb", "~> 0.0.2"
22
+ # Require the gem
23
+ require 'particle'
24
+ ```
22
25
 
23
26
 
24
27
  ### Providing credentials
@@ -129,12 +132,18 @@ device = Particle.device('f8bbe1e6e69e05c9c405ba1ca504d438061f1b0d')
129
132
  device.variable('version') # ==> "1.0.1"
130
133
  ```
131
134
 
132
-
133
135
  Signal a device to start blinking the RGB LED in rainbow patterns. Returns whether the device is signaling.
134
136
 
135
137
  ```ruby
136
138
  Particle.device('nyan_cat').signal(true)
137
139
  ```
140
+
141
+ Change the product id. The meaning of the product id is specific to your application and account.
142
+
143
+ ```ruby
144
+ Particle.device('f8bbe1e6e69e05c9c405ba1ca504d438061f1b0d').change_product(3)
145
+ ```
146
+
138
147
  See the [Particle Cloud API documentation about devices][device docs] for more details.
139
148
 
140
149
  [device docs]: http://docs.particle.io/core/api/#introduction-device-information
@@ -199,6 +208,21 @@ Create a new webhook. Pass a hash of [any options accepted by the Particle Cloud
199
208
  ```ruby
200
209
  Particle.webhook(event: "weather", url: "http://myserver.com/report").create
201
210
  ```
211
+
212
+ Currently the available options are:
213
+
214
+ * event
215
+ * url
216
+ * deviceid
217
+ * requestType
218
+ * headers
219
+ * json
220
+ * query
221
+ * auth
222
+ * mydevices
223
+ * rejectUnauthorized
224
+
225
+
202
226
  See the [Particle Cloud API documentation about webhooks][webhook docs] for more details.
203
227
 
204
228
  [webhook docs]: http://docs.particle.io/core/webhooks/
@@ -236,6 +260,11 @@ Create a token but don't set it on the client. Returns a `Particle::Token`
236
260
  Particle.token.create("me@example.com", "pa$$w0rd")
237
261
  ```
238
262
 
263
+ `login` and `token.create` take an optional hash of options.
264
+
265
+ * `expires_in`: number of seconds that the token will be valid
266
+ * `expires_at`: `Date` when the token will become invalid
267
+
239
268
  Invalidate and delete a token. Returns true on success.
240
269
 
241
270
  ```ruby
@@ -247,6 +276,45 @@ See the [Particle Cloud API documentation about authentication and token][authen
247
276
 
248
277
  [authentication docs]: http://docs.particle.io/core/api/#introduction-authentication
249
278
 
279
+ ## Compiling and flashing
280
+
281
+ Flash new firmware from source. Returns a result struct
282
+
283
+ ```ruby
284
+ result = device.flash('blink_led.ino')
285
+ result.ok # ==> true
286
+
287
+ result = device.flash('bad_code.ino')
288
+ result.ok # ==> false
289
+ result.errors # ==> "Compiler errors\n...\n"
290
+
291
+ device.flash(Dir.glob('firmware/*') # all files in a directory
292
+ device.flash('application.bin', binary: true)
293
+ ```
294
+
295
+ Compile firmware for a specific device, platform or product. Returns a result struct
296
+
297
+ ```ruby
298
+ result = device.compile('blink_led.ino')
299
+ result.ok # ==> true
300
+ result.binary_id # ==> "559061e16b4ba27e4602c5c8"
301
+
302
+ Particle.compile_code(Dir.glob('firmware/*', platform: :core) # or :photon
303
+ Particle.compile_code(Dir.glob('firmware/*', product_id: 1) # meaning depends on your account
304
+ ```
305
+
306
+ Download a compiled binary. Returns the result bytes
307
+
308
+ ```ruby
309
+ result = device.compile('blink_led.ino')
310
+ binary = Particle.download_binary(result.binary_id)
311
+ File.new('application.bin', 'w') { |f| f.write(binary) }
312
+ ```
313
+
314
+ See the [Particle Cloud API documentation about firmware][firmware docs] for more details.
315
+
316
+ [firmware docs]: http://docs.particle.io/core/api/#basic-functions-verifying-and-flashing-new-firmware
317
+
250
318
 
251
319
  ## Errors
252
320
 
@@ -264,6 +332,8 @@ The actual error classes are
264
332
 
265
333
  See [a description of each error on the Particle API docs][error docs].
266
334
 
335
+ This gem uses the Faraday HTTP client library, so API call may raise `Faraday::ClientError` for things like SSL errors, DNS errors, HTTP connection timed out.
336
+
267
337
  [error docs]: http://docs.particle.io/core/api/#introduction-errors
268
338
 
269
339
  ## Advanced
@@ -3,6 +3,7 @@ require 'particle/client/devices'
3
3
  require 'particle/client/publish'
4
4
  require 'particle/client/webhooks'
5
5
  require 'particle/client/tokens'
6
+ require 'particle/client/firmware'
6
7
 
7
8
  module Particle
8
9
 
@@ -16,6 +17,7 @@ module Particle
16
17
  include Particle::Client::Publish
17
18
  include Particle::Client::Webhooks
18
19
  include Particle::Client::Tokens
20
+ include Particle::Client::Firmware
19
21
 
20
22
  def initialize(options = {})
21
23
  # Use options passed in, but fall back to module defaults
@@ -42,7 +44,7 @@ module Particle
42
44
  #
43
45
  # @param value [String] 40 character Particle OAuth2 access token
44
46
  def access_token=(value)
45
- reset_agent
47
+ reset_connection
46
48
  @access_token =
47
49
  if value.respond_to? :access_token
48
50
  value.access_token
@@ -10,13 +10,11 @@ module Particle
10
10
 
11
11
  # Create a domain model for a Particle device
12
12
  #
13
- # @param target [String, Sawyer::Resource, Device] A device id, name, Sawyer::Resource or {Device} object
13
+ # @param target [String, Hash, Device] A device id, name, hash of attributes or {Device} object
14
14
  # @return [Device] A device object to interact with
15
15
  def device(target)
16
16
  if target.is_a? Device
17
17
  target
18
- elsif target.respond_to?(:to_attrs)
19
- Device.new(self, target.to_attrs)
20
18
  else
21
19
  Device.new(self, target)
22
20
  end
@@ -26,8 +24,8 @@ module Particle
26
24
  #
27
25
  # @return [Array<Device>] List of Particle devices to interact with
28
26
  def devices
29
- get(Device.list_path).map do |resource|
30
- device(resource)
27
+ get(Device.list_path).map do |attributes|
28
+ device(attributes)
31
29
  end
32
30
  end
33
31
 
@@ -36,8 +34,7 @@ module Particle
36
34
  # @param target [String, Device] A device id, name or {Device} object
37
35
  # @return [Hash] The device attributes
38
36
  def device_attributes(target)
39
- result = get(device(target).path)
40
- result.to_attrs
37
+ get(device(target).path)
41
38
  end
42
39
 
43
40
  # Add a Particle device to your account
@@ -47,7 +44,7 @@ module Particle
47
44
  # @return [Device] A device object to interact with
48
45
  def claim_device(target)
49
46
  result = post(Device.claim_path, id: device(target).id_or_name)
50
- device(result.id)
47
+ device(result[:id])
51
48
  end
52
49
 
53
50
  # Remove a Particle device from your account
@@ -56,7 +53,7 @@ module Particle
56
53
  # @return [boolean] true for success
57
54
  def remove_device(target)
58
55
  result = delete(device(target).path)
59
- result.ok
56
+ result[:ok]
60
57
  end
61
58
 
62
59
  # Rename a Particle device in your account
@@ -66,7 +63,7 @@ module Particle
66
63
  # @return [boolean] true for success
67
64
  def rename_device(target, name)
68
65
  result = put(device(target).path, name: name)
69
- result.name == name
66
+ result[:name] == name
70
67
  end
71
68
 
72
69
  # Call a function in the firmware of a Particle device
@@ -77,7 +74,7 @@ module Particle
77
74
  # @return [Integer] Return value from the firmware function
78
75
  def call_function(target, name, argument = "")
79
76
  result = post(device(target).function_path(name), arg: argument)
80
- result.return_value
77
+ result[:return_value]
81
78
  end
82
79
 
83
80
  # Get the value of a variable in the firmware of a Particle device
@@ -87,7 +84,7 @@ module Particle
87
84
  # @return [String, Number] Value from the firmware variable
88
85
  def get_variable(target, name)
89
86
  result = get(device(target).variable_path(name))
90
- result.result
87
+ result[:result]
91
88
  end
92
89
 
93
90
  # Signal the device to start blinking the RGB LED in a rainbow
@@ -99,12 +96,33 @@ module Particle
99
96
  def signal_device(target, enabled = true)
100
97
  result = put(device(target).path, signal: enabled ? '1' : '0')
101
98
  # FIXME: API bug. Should return HTTP 408 so result.ok wouldn't be necessary
102
- if result.ok == false
99
+ if result[:ok] == false
103
100
  false
104
101
  else
105
- result.signaling
102
+ result[:signaling]
106
103
  end
107
104
  end
105
+
106
+ # Change the product_id on the device.
107
+ # Use this carefully, it will impact what updates you receive, and
108
+ # can only be used for products that have given their permission
109
+ #
110
+ # @param target [String, Device] A device id, name or {Device} object
111
+ # @param product_id [String] New product id
112
+ # @param should_update [String] if the device should be
113
+ # immediately updated after changing the product_id
114
+ # @return [boolean] true on success
115
+ def change_device_product(target, product_id, should_update = false)
116
+ params = {
117
+ product_id: product_id,
118
+ update_after_claim: should_update
119
+ }
120
+ result = put(device(target).path, params)
121
+ if result[:error] == "Nothing to do?"
122
+ result[:ok] = false
123
+ end
124
+ result[:ok]
125
+ end
108
126
  end
109
127
  end
110
128
  end
@@ -0,0 +1,107 @@
1
+ require 'particle/device'
2
+ require 'ostruct'
3
+
4
+ module Particle
5
+ class Client
6
+
7
+ # Client methods for the Particle firmware flash API
8
+ #
9
+ # @see http://docs.particle.io/core/api/#basic-functions-verifying-and-flashing-new-firmware
10
+ module Firmware
11
+ COMPILE_PATH = "v1/binaries"
12
+ PLATFORMS = {
13
+ core: 0,
14
+ photon: 1
15
+ }
16
+
17
+ # Flash new firmware to a Particle device from source code or
18
+ # binary
19
+ #
20
+ # @param target [String, Device] A device id, name or {Device} object that will
21
+ # receive the new firmware
22
+ # @param file_paths [Array<String>] File paths to send to cloud
23
+ # and flash
24
+ # @param options [Hash] Flashing options
25
+ # :binary => true to skip the compile stage
26
+ # @return [OpenStruct] Result of flashing.
27
+ # :ok => true on success
28
+ # :errors => String with compile errors
29
+ #
30
+ def flash_device(target, file_paths, options = {})
31
+ params = file_upload_params(file_paths, options)
32
+ result = put(device(target).path, params)
33
+ # Normalize the weird output structure
34
+ if result[:ok] == false
35
+ errors = result[:errors][0]
36
+ result[:errors] = if errors.is_a? Hash
37
+ errors[:errors][0]
38
+ else
39
+ result
40
+ end
41
+ elsif result[:status] == "Update started"
42
+ result[:ok] = true
43
+ end
44
+ OpenStruct.new(result)
45
+ end
46
+
47
+ # Compile firmware from source code for a specific Particle device
48
+ #
49
+ # @param file_paths [Array<String>] File paths to send to cloud
50
+ # and flash
51
+ # @param options [Hash] Compilation options
52
+ # :device_id => Compile for a specific device
53
+ # :platform => Compile for a specific platform (:core or :photon)
54
+ # :platform_id => Compile for a specific platform id
55
+ # :product_id => Compile for a specific product
56
+ # @return [OpenStruct] Result of flashing.
57
+ # :ok => true on success
58
+ # :errors => String with compile errors
59
+ #
60
+ def compile_code(file_paths, options = {})
61
+ normalize_platform_id(options)
62
+ params = file_upload_params(file_paths, options)
63
+ result = post(COMPILE_PATH, params)
64
+ # Normalize the weird output structure
65
+ if result[:ok] == false
66
+ result[:errors] = result[:errors][0]
67
+ end
68
+ OpenStruct.new(result)
69
+ end
70
+
71
+ # Download compiled binary firmware
72
+ #
73
+ # @param binary_id [String] Id of the compiled binary to download
74
+ # @return [String] Binary bytes
75
+ #
76
+ def download_binary(binary_id)
77
+ get(binary_path(binary_id))
78
+ end
79
+
80
+ private
81
+
82
+ def binary_path(id)
83
+ COMPILE_PATH + "/#{id}"
84
+ end
85
+
86
+ def file_upload_params(file_paths, options)
87
+ params = {}
88
+ mime_type = options[:binary] ? "application/octet-stream" : "text/plain"
89
+
90
+ file_paths = [file_paths] unless file_paths.is_a? Array
91
+ file_paths.each_with_index do |file, index|
92
+ params[:"file#{index > 0 ? index : ""}"] =
93
+ Faraday::UploadIO.new(file, mime_type)
94
+ end
95
+ params[:file_type] = "binary" if options.delete(:binary)
96
+ params.merge! options
97
+ params
98
+ end
99
+
100
+ def normalize_platform_id(options)
101
+ if options[:platform]
102
+ options[:platform_id] = PLATFORMS[options.delete(:platform)]
103
+ end
104
+ end
105
+ end
106
+ end
107
+ end
@@ -1,5 +1,3 @@
1
- require 'particle/event'
2
-
3
1
  module Particle
4
2
  class Client
5
3
 
@@ -7,6 +5,7 @@ module Particle
7
5
  #
8
6
  # @see http://docs.particle.io/core/api/#publishing-events
9
7
  module Publish
8
+ PUBLISH_PATH = "v1/devices/events"
10
9
 
11
10
  # Publish an event to your devices
12
11
  #
@@ -30,8 +29,8 @@ module Particle
30
29
  params[:ttl] = options[:ttl] if options[:ttl]
31
30
  params[:private] = true if options[:private]
32
31
 
33
- result = post(Event.publish_path, params)
34
- result.ok
32
+ result = post(PUBLISH_PATH, params)
33
+ result[:ok]
35
34
  end
36
35
  end
37
36
  end
@@ -11,13 +11,11 @@ module Particle
11
11
 
12
12
  # Create a domain model for a Particle token
13
13
  #
14
- # @param target [String, Sawyer::Resource, Token] A token id, Sawyer::Resource or {Token} object
14
+ # @param target [String, Hash, Token] A token id, hash of attributes or {Token} object
15
15
  # @return [Token] A token object to interact with
16
16
  def token(target = {})
17
17
  if target.is_a? Token
18
18
  target
19
- elsif target.respond_to?(:to_attrs)
20
- Token.new(self, target.to_attrs)
21
19
  else
22
20
  Token.new(self, target)
23
21
  end
@@ -35,8 +33,8 @@ module Particle
35
33
  username: username,
36
34
  password: password
37
35
  }
38
- request(:get, Token.list_path, "", http_options).map do |resource|
39
- token(resource)
36
+ request(:get, Token.list_path, "", http_options).map do |attributes|
37
+ token(attributes)
40
38
  end
41
39
  end
42
40
 
@@ -46,8 +44,11 @@ module Particle
46
44
  # the Particle Cloud API
47
45
  # @param password [String] The password used to log in to
48
46
  # the Particle Cloud API
49
- # @param options [Hash] Additional Particle Cloud API options to
47
+ # @param options [Hash] Optional Particle Cloud API options to
50
48
  # create the token.
49
+ # :expires_in => How many seconds should the token last for?
50
+ # 0 means a token that never expires
51
+ # :expires_at => Date and time when should the token expire
51
52
  # @return [Token] The token object
52
53
  def create_token(username, password, options = {})
53
54
  data = URI.encode_www_form({
@@ -61,7 +62,8 @@ module Particle
61
62
  password: 'particle' # specified by docs
62
63
  }
63
64
  result = request(:post, Token.create_path, data, http_options)
64
- token(result.access_token)
65
+ result[:token] = result.delete(:access_token)
66
+ token(result)
65
67
  end
66
68
 
67
69
  # Authenticate with Particle and start using the token on the
@@ -94,7 +96,7 @@ module Particle
94
96
  password: password
95
97
  }
96
98
  result = request(:delete, token(target).path, "", http_options)
97
- result.ok
99
+ result[:ok]
98
100
  end
99
101
  end
100
102
  end
@@ -10,13 +10,11 @@ module Particle
10
10
 
11
11
  # Create a domain model for a Particle webhook
12
12
  #
13
- # @param target [String, Sawyer::Resource, Webhook] A webhook id, Sawyer::Resource or {Device} object
13
+ # @param target [String, Hash, Webhook] A webhook id, hash of attributes or {Device} object
14
14
  # @return [Webhook] A webhook object to interact with
15
15
  def webhook(target)
16
16
  if target.is_a? Webhook
17
17
  target
18
- elsif target.respond_to?(:to_attrs)
19
- Webhook.new(self, target.to_attrs)
20
18
  else
21
19
  Webhook.new(self, target)
22
20
  end
@@ -26,8 +24,8 @@ module Particle
26
24
  #
27
25
  # @return [Array<Webhook>] List of Particle webhooks to interact with
28
26
  def webhooks
29
- get(Webhook.list_path).map do |resource|
30
- webhook(resource)
27
+ get(Webhook.list_path).map do |attributes|
28
+ webhook(attributes)
31
29
  end
32
30
  end
33
31
 
@@ -39,8 +37,7 @@ module Particle
39
37
  # @param target [String, Webhook] A webhook id or {Webhook} object
40
38
  # @return [Hash] The webhook attributes and test message response
41
39
  def webhook_attributes(target)
42
- result = get(webhook(target).path)
43
- result.to_attrs
40
+ get(webhook(target).path)
44
41
  end
45
42
 
46
43
  # Creates a new Particle webhook
@@ -59,7 +56,7 @@ module Particle
59
56
  # @return [boolean] true for success
60
57
  def remove_webhook(target)
61
58
  result = delete(webhook(target).path)
62
- result.ok
59
+ result[:ok]
63
60
  end
64
61
  end
65
62
  end
@@ -1,5 +1,7 @@
1
- require 'sawyer'
1
+ require 'faraday'
2
+ require 'faraday_middleware'
2
3
  require 'particle/response/raise_error'
4
+ require 'particle/response/parse_json_symbols'
3
5
 
4
6
  module Particle
5
7
 
@@ -9,6 +11,11 @@ module Particle
9
11
  # Faraday middleware stack
10
12
  MIDDLEWARE = Faraday::RackBuilder.new do |builder|
11
13
  builder.use Particle::Response::RaiseError
14
+ # For file upload
15
+ builder.request :multipart
16
+
17
+ builder.request :json
18
+ builder.use Particle::Response::ParseJsonSymbols, :content_type => /\bjson$/
12
19
  builder.adapter Faraday.default_adapter
13
20
  end
14
21
 
@@ -16,7 +23,7 @@ module Particle
16
23
  #
17
24
  # @param url [String] The path, relative to {#api_endpoint}
18
25
  # @param options [Hash] Query and header params for request
19
- # @return [Sawyer::Resource]
26
+ # @return [Hash] JSON response as a hash
20
27
  def get(url, options = {})
21
28
  request :get, url, options
22
29
  end
@@ -25,7 +32,7 @@ module Particle
25
32
  #
26
33
  # @param url [String] The path, relative to {#api_endpoint}
27
34
  # @param options [Hash] Body and header params for request
28
- # @return [Sawyer::Resource]
35
+ # @return [Hash] JSON response as a hash
29
36
  def post(url, options = {})
30
37
  request :post, url, options
31
38
  end
@@ -34,7 +41,7 @@ module Particle
34
41
  #
35
42
  # @param url [String] The path, relative to {#api_endpoint}
36
43
  # @param options [Hash] Body and header params for request
37
- # @return [Sawyer::Resource]
44
+ # @return [Hash] JSON response as a hash
38
45
  def put(url, options = {})
39
46
  request :put, url, options
40
47
  end
@@ -43,7 +50,7 @@ module Particle
43
50
  #
44
51
  # @param url [String] The path, relative to {#api_endpoint}
45
52
  # @param options [Hash] Body and header params for request
46
- # @return [Sawyer::Resource]
53
+ # @return [Hash] JSON response as a hash
47
54
  def patch(url, options = {})
48
55
  request :patch, url, options
49
56
  end
@@ -52,18 +59,17 @@ module Particle
52
59
  #
53
60
  # @param url [String] The path, relative to {#api_endpoint}
54
61
  # @param options [Hash] Query and header params for request
55
- # @return [Sawyer::Resource]
62
+ # @return [Hash] JSON response as a hash
56
63
  def delete(url, options = {})
57
64
  request :delete, url, options
58
65
  end
59
66
 
60
- # Hypermedia agent for the Particle API
67
+ # HTTP connection for the Particle API
61
68
  #
62
- # @return [Sawyer::Agent]
63
- def agent
64
- @agent ||= Sawyer::Agent.new(endpoint, sawyer_options) do |http|
65
- http.headers[:content_type] = "application/json"
66
- http.headers[:user_agent] = user_agent
69
+ # @return [Faraday::Connection]
70
+ def connection
71
+ @connection ||= Faraday.new(conn_opts) do |http|
72
+ http.url_prefix = endpoint
67
73
  if @access_token
68
74
  http.authorization :Bearer, @access_token
69
75
  end
@@ -72,7 +78,7 @@ module Particle
72
78
 
73
79
  # Response for last HTTP request
74
80
  #
75
- # @return [Sawyer::Response]
81
+ # @return [Faraday::Response]
76
82
  attr_reader :last_response
77
83
 
78
84
  protected
@@ -83,8 +89,8 @@ module Particle
83
89
 
84
90
  private
85
91
 
86
- def reset_agent
87
- @agent = nil
92
+ def reset_connection
93
+ @connection = nil
88
94
  end
89
95
 
90
96
  def request(method, path, data, options = {})
@@ -104,20 +110,24 @@ module Particle
104
110
  basic_auth_header(username, password)
105
111
  end
106
112
 
107
- @last_response = response = agent.call(method, URI::Parser.new.escape(path.to_s), data, options)
108
- response.data
113
+ @last_response = response = connection.send(method, URI::Parser.new.escape(path.to_s)) do |req|
114
+ if data && method != :get
115
+ req.body = data
116
+ end
117
+ if params = options[:query]
118
+ req.params.update params
119
+ end
120
+ if headers = options[:headers]
121
+ req.headers.update headers
122
+ end
123
+ end
124
+ response.body
109
125
  end
110
126
 
111
- def sawyer_options
112
- opts = {
113
- :links_parser => Sawyer::LinkParsers::Simple.new
114
- }
127
+ def conn_opts
115
128
  conn_opts = @connection_options.dup
116
129
  conn_opts[:builder] = MIDDLEWARE
117
- conn_opts[:proxy] = @proxy if @proxy
118
- opts[:faraday] = Faraday.new(conn_opts)
119
-
120
- opts
130
+ conn_opts
121
131
  end
122
132
 
123
133
  # Temporarily set the Authorization to use basic auth
@@ -98,6 +98,45 @@ module Particle
98
98
  @client.signal_device(self, enabled)
99
99
  end
100
100
 
101
+ # Flash new firmware to this device from source code or
102
+ # binary
103
+ #
104
+ # @param file_paths [Array<String>] File paths to send to cloud
105
+ # and flash
106
+ # @param options [Hash] Flashing options
107
+ # :binary => true to skip the compile stage
108
+ # @return [OpenStruct] Result of flashing.
109
+ # :ok => true on success
110
+ # :errors => String with compile errors
111
+ #
112
+ def flash(file_paths, options = {})
113
+ @client.flash_device(self, file_paths, options)
114
+ end
115
+
116
+ # Compile firmware from source code for this device
117
+ #
118
+ # @param file_paths [Array<String>] File paths to send to cloud
119
+ # and flash
120
+ # @return [OpenStruct] Result of flashing.
121
+ # :ok => true on success
122
+ # :errors => String with compile errors
123
+ #
124
+ def compile(file_paths)
125
+ @client.compile_code(file_paths, device_id: id)
126
+ end
127
+
128
+ # Change the product_id on the device.
129
+ # Use this carefully, it will impact what updates you receive, and
130
+ # can only be used for products that have given their permission
131
+ #
132
+ # @param product_id [String] New product id
133
+ # @param should_update [String] if the device should be
134
+ # immediately updated after changing the product_id
135
+ # @return [boolean] true on success
136
+ def change_product(product_id, should_update = false)
137
+ @client.change_device_product(self, product_id, should_update)
138
+ end
139
+
101
140
  def self.list_path
102
141
  "v1/devices"
103
142
  end
@@ -0,0 +1,18 @@
1
+ require 'faraday_middleware/response_middleware'
2
+
3
+ module Particle
4
+ # Faraday response middleware
5
+ module Response
6
+
7
+ # Parse response bodies as JSON with symbol keys
8
+ class ParseJsonSymbols < FaradayMiddleware::ResponseMiddleware
9
+ dependency do
10
+ require 'json' unless defined?(::JSON)
11
+ end
12
+
13
+ define_parser do |body|
14
+ ::JSON.parse(body, symbolize_names: true) unless body.strip.empty?
15
+ end
16
+ end
17
+ end
18
+ end
@@ -1,3 +1,3 @@
1
1
  module Particle
2
- VERSION = "0.0.2".freeze
2
+ VERSION = "0.0.3".freeze
3
3
  end
@@ -17,12 +17,14 @@ Gem::Specification.new do |spec|
17
17
  spec.required_ruby_version = '>= 1.9.3'
18
18
  spec.required_rubygems_version = '>= 1.3.5'
19
19
  spec.version = Particle::VERSION.dup
20
- spec.add_dependency 'sawyer', '~> 0.6.0'
20
+ spec.add_dependency 'faraday', '~> 0.9.0'
21
+ spec.add_dependency 'faraday_middleware', '~> 0.9.0'
21
22
  spec.add_development_dependency 'bundler', '~> 1.0'
22
23
  spec.add_development_dependency 'rake', '~> 10.0'
23
24
  spec.add_development_dependency 'guard-rspec', '~> 4.5'
24
25
  spec.add_development_dependency 'pry', '~> 0.10'
25
26
  spec.add_development_dependency 'rspec', '~> 3.0'
27
+ spec.add_development_dependency 'rspec-pride', '~> 3.1'
26
28
  spec.add_development_dependency 'vcr', '~> 2.9'
27
29
  spec.add_development_dependency 'webmock', '~> 1.21'
28
30
  spec.add_development_dependency 'multi_json', '~> 1.11'
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: particlerb
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Julien Vanier
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-06-27 00:00:00.000000000 Z
11
+ date: 2015-06-28 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: sawyer
14
+ name: faraday
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
17
  - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 0.6.0
19
+ version: 0.9.0
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 0.6.0
26
+ version: 0.9.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: faraday_middleware
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 0.9.0
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 0.9.0
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: bundler
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -94,6 +108,20 @@ dependencies:
94
108
  - - "~>"
95
109
  - !ruby/object:Gem::Version
96
110
  version: '3.0'
111
+ - !ruby/object:Gem::Dependency
112
+ name: rspec-pride
113
+ requirement: !ruby/object:Gem::Requirement
114
+ requirements:
115
+ - - "~>"
116
+ - !ruby/object:Gem::Version
117
+ version: '3.1'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ requirements:
122
+ - - "~>"
123
+ - !ruby/object:Gem::Version
124
+ version: '3.1'
97
125
  - !ruby/object:Gem::Dependency
98
126
  name: vcr
99
127
  requirement: !ruby/object:Gem::Requirement
@@ -149,6 +177,7 @@ files:
149
177
  - lib/particle.rb
150
178
  - lib/particle/client.rb
151
179
  - lib/particle/client/devices.rb
180
+ - lib/particle/client/firmware.rb
152
181
  - lib/particle/client/publish.rb
153
182
  - lib/particle/client/tokens.rb
154
183
  - lib/particle/client/webhooks.rb
@@ -157,8 +186,8 @@ files:
157
186
  - lib/particle/default.rb
158
187
  - lib/particle/device.rb
159
188
  - lib/particle/error.rb
160
- - lib/particle/event.rb
161
189
  - lib/particle/model.rb
190
+ - lib/particle/response/parse_json_symbols.rb
162
191
  - lib/particle/response/raise_error.rb
163
192
  - lib/particle/token.rb
164
193
  - lib/particle/version.rb
@@ -1,10 +0,0 @@
1
- module Particle
2
-
3
- # Domain model for Particle event
4
- class Event
5
- def self.publish_path
6
- "v1/devices/events"
7
- end
8
- end
9
- end
10
-