particlerb 0.0.2 → 0.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|