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 +4 -4
- data/README.md +76 -6
- data/lib/particle/client.rb +3 -1
- data/lib/particle/client/devices.rb +32 -14
- data/lib/particle/client/firmware.rb +107 -0
- data/lib/particle/client/publish.rb +3 -4
- data/lib/particle/client/tokens.rb +10 -8
- data/lib/particle/client/webhooks.rb +5 -8
- data/lib/particle/connection.rb +35 -25
- data/lib/particle/device.rb +39 -0
- data/lib/particle/response/parse_json_symbols.rb +18 -0
- data/lib/particle/version.rb +1 -1
- data/particlerb.gemspec +3 -1
- metadata +35 -6
- data/lib/particle/event.rb +0 -10
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 69be1802b2959a94182268ee4dc69983a7675941
|
4
|
+
data.tar.gz: 42eed9eebd4ff5fb83ae18a4404886d31ecee5c8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
16
|
-
|
17
|
-
|
15
|
+
```
|
16
|
+
# Install via Rubygems
|
17
|
+
$ gem install particlerb
|
18
18
|
|
19
|
-
|
19
|
+
# or add to your Gemfile
|
20
|
+
gem "particlerb", "~> 0.0.3"
|
20
21
|
|
21
|
-
|
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
|
data/lib/particle/client.rb
CHANGED
@@ -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
|
-
|
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,
|
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 |
|
30
|
-
device(
|
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
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
99
|
+
if result[:ok] == false
|
103
100
|
false
|
104
101
|
else
|
105
|
-
result
|
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(
|
34
|
-
result
|
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,
|
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 |
|
39
|
-
token(
|
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]
|
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
|
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
|
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,
|
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 |
|
30
|
-
webhook(
|
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
|
-
|
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
|
59
|
+
result[:ok]
|
63
60
|
end
|
64
61
|
end
|
65
62
|
end
|
data/lib/particle/connection.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
require '
|
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 [
|
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 [
|
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 [
|
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 [
|
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 [
|
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
|
-
#
|
67
|
+
# HTTP connection for the Particle API
|
61
68
|
#
|
62
|
-
# @return [
|
63
|
-
def
|
64
|
-
@
|
65
|
-
http.
|
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 [
|
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
|
87
|
-
@
|
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 =
|
108
|
-
|
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
|
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
|
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
|
data/lib/particle/device.rb
CHANGED
@@ -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
|
data/lib/particle/version.rb
CHANGED
data/particlerb.gemspec
CHANGED
@@ -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 '
|
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.
|
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-
|
11
|
+
date: 2015-06-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
|
-
name:
|
14
|
+
name: faraday
|
15
15
|
requirement: !ruby/object:Gem::Requirement
|
16
16
|
requirements:
|
17
17
|
- - "~>"
|
18
18
|
- !ruby/object:Gem::Version
|
19
|
-
version: 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.
|
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
|