smartcar 2.4.0 → 2.5.0
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/.rubocop.yml +28 -0
- data/Gemfile +4 -2
- data/Gemfile.lock +22 -1
- data/Rakefile +11 -3
- data/bin/console +4 -3
- data/lib/smartcar.rb +36 -26
- data/lib/smartcar/base.rb +14 -12
- data/lib/smartcar/battery.rb +6 -4
- data/lib/smartcar/battery_capacity.rb +4 -2
- data/lib/smartcar/charge.rb +6 -4
- data/lib/smartcar/engine_oil.rb +5 -3
- data/lib/smartcar/fuel.rb +8 -6
- data/lib/smartcar/location.rb +5 -3
- data/lib/smartcar/oauth.rb +45 -37
- data/lib/smartcar/odometer.rb +4 -2
- data/lib/smartcar/permissions.rb +4 -2
- data/lib/smartcar/tire_pressure.rb +11 -10
- data/lib/smartcar/user.rb +7 -4
- data/lib/smartcar/utils.rb +14 -5
- data/lib/smartcar/vehicle.rb +19 -242
- data/lib/smartcar/vehicle_attributes.rb +7 -5
- data/lib/smartcar/vehicle_utils/actions.rb +61 -0
- data/lib/smartcar/vehicle_utils/batch.rb +83 -0
- data/lib/smartcar/vehicle_utils/data.rb +110 -0
- data/lib/smartcar/version.rb +3 -1
- data/lib/smartcar/vin.rb +4 -2
- data/ruby-sdk.gemspec +24 -21
- metadata +29 -11
data/lib/smartcar/odometer.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Smartcar
|
2
4
|
# class to represent Odometer
|
3
|
-
|
5
|
+
# @attr [Number] distanceLast recorded odometer reading.
|
4
6
|
class Odometer < Base
|
5
7
|
# Path Proc for hitting odometer end point
|
6
|
-
PATH =
|
8
|
+
PATH = proc { |id| "/vehicles/#{id}/odometer" }
|
7
9
|
attr_reader :distance
|
8
10
|
end
|
9
11
|
end
|
data/lib/smartcar/permissions.rb
CHANGED
@@ -1,9 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Smartcar
|
2
4
|
# class to represent permissions response
|
3
|
-
|
5
|
+
# @attr [Array] permissions Array of permissions granted on the vehicle.
|
4
6
|
class Permissions < Base
|
5
7
|
# Path Proc for hitting permissions end point
|
6
|
-
PATH =
|
8
|
+
PATH = proc { |id| "/vehicles/#{id}/permissions" }
|
7
9
|
attr_reader :permissions
|
8
10
|
end
|
9
11
|
end
|
@@ -1,19 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Smartcar
|
2
4
|
# class to represent Tire Pressure response
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
5
|
+
# @attr [Number] back_left Last recorded tire pressure of the back left tire.
|
6
|
+
# @attr [Number] back_right Last recorded tire pressure of the back right tire.
|
7
|
+
# @attr [Number] front_left Last recorded tire pressure of the front left tire.
|
8
|
+
# @attr [Number] front_right Last recorded tire pressure of the front right tire.
|
8
9
|
class TirePressure < Base
|
9
10
|
# Path Proc for hitting tire pressure end point
|
10
|
-
PATH =
|
11
|
+
PATH = proc { |id| "/vehicles/#{id}/tires/pressure" }
|
11
12
|
attr_reader :backLeft, :backRight, :frontLeft, :frontRight
|
12
13
|
|
13
14
|
# just to have Ruby-esque method names
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
15
|
+
alias back_left backLeft
|
16
|
+
alias back_right backRight
|
17
|
+
alias front_left frontLeft
|
18
|
+
alias front_right frontRight
|
18
19
|
end
|
19
20
|
end
|
data/lib/smartcar/user.rb
CHANGED
@@ -1,10 +1,12 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Smartcar
|
2
4
|
# Class to get to user API.
|
3
|
-
|
4
|
-
|
5
|
+
# @attr [String] id Smartcar user id.
|
6
|
+
# @attr [String] token Access token used to connect to Smartcar API.
|
5
7
|
class User < Base
|
6
8
|
# Path for hitting user end point
|
7
|
-
USER_PATH = '/user'
|
9
|
+
USER_PATH = '/user'
|
8
10
|
attr_reader :id
|
9
11
|
|
10
12
|
# Class method Used to get user id
|
@@ -15,7 +17,8 @@ module Smartcar
|
|
15
17
|
# @return [String] User ID
|
16
18
|
def self.user_id(token:, version: Smartcar.get_api_version)
|
17
19
|
# @deprecated Please use {#get} instead
|
18
|
-
warn
|
20
|
+
warn '[DEPRECATION] `Smartcar::User.user_id` is deprecated and will be removed in next major version update.
|
21
|
+
Please use `Smartcar::User.get` instead.'
|
19
22
|
get(token: token, version: version).id
|
20
23
|
end
|
21
24
|
|
data/lib/smartcar/utils.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
#
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
2
3
|
module Smartcar
|
4
|
+
# Utils module , provides utility methods to underlying classes
|
3
5
|
module Utils
|
4
6
|
# A constructor to take a hash and assign it to the instance variables
|
5
7
|
# @param options = {} [Hash] Could by any class's hash, but the first level keys should be defined in the class
|
@@ -16,7 +18,7 @@ module Smartcar
|
|
16
18
|
# @return [Hash] hash of all instance variables
|
17
19
|
def to_hash
|
18
20
|
instance_variables.each_with_object({}) do |attribute, hash|
|
19
|
-
hash[attribute.to_s.delete(
|
21
|
+
hash[attribute.to_s.delete('@').to_sym] = instance_variable_get(attribute)
|
20
22
|
end
|
21
23
|
end
|
22
24
|
|
@@ -27,6 +29,7 @@ module Smartcar
|
|
27
29
|
def get_config(config_name)
|
28
30
|
config_name = "INTEGRATION_#{config_name}" if ENV['MODE'] == 'test'
|
29
31
|
raise Smartcar::ConfigNotFound, "Environment variable #{config_name} not found !" unless ENV[config_name]
|
32
|
+
|
30
33
|
ENV[config_name]
|
31
34
|
end
|
32
35
|
|
@@ -36,11 +39,17 @@ module Smartcar
|
|
36
39
|
# @return [Object] nil OR Error object
|
37
40
|
def get_error(response)
|
38
41
|
status = response.status
|
39
|
-
return nil if [200,204].include?(status)
|
42
|
+
return nil if [200, 204].include?(status)
|
40
43
|
return Smartcar::ServiceUnavailableError.new("Service Unavailable - #{response.body}") if status == 404
|
41
44
|
return Smartcar::BadRequestError.new("Bad Request - #{response.body}") if status == 400
|
42
|
-
return Smartcar::AuthenticationError.new(
|
43
|
-
|
45
|
+
return Smartcar::AuthenticationError.new('Authentication error') if status == 401
|
46
|
+
|
47
|
+
Smartcar::ExternalServiceError.new("API error - #{response.body}")
|
48
|
+
end
|
49
|
+
|
50
|
+
def handle_errors(response)
|
51
|
+
error = get_error(response)
|
52
|
+
raise error if error
|
44
53
|
end
|
45
54
|
end
|
46
55
|
end
|
data/lib/smartcar/vehicle.rb
CHANGED
@@ -1,25 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Smartcar
|
2
4
|
# Vehicle class to connect to vehicle basic info,disconnect, lock unlock and get all vehicles API
|
3
5
|
# For ease of use, this also has methods define to be able to call other resources on a vehicle object
|
4
6
|
# For Ex. Vehicle object will be treate as an entity and doing vehicle_object.
|
5
7
|
# Battery should return Battery object.
|
6
8
|
#
|
7
|
-
|
8
|
-
|
9
|
-
|
9
|
+
# @attr [String] token Access token used to connect to Smartcar API.
|
10
|
+
# @attr [String] id Smartcar vehicle ID.
|
11
|
+
# @attr [String] unit_system unit system to represent the data in.
|
10
12
|
class Vehicle < Base
|
13
|
+
include VehicleUtils::Data
|
14
|
+
include VehicleUtils::Actions
|
15
|
+
include VehicleUtils::Batch
|
11
16
|
# Path for hitting compatibility end point
|
12
|
-
COMPATIBLITY_PATH = '/compatibility'
|
17
|
+
COMPATIBLITY_PATH = '/compatibility'
|
13
18
|
|
14
19
|
# Path for hitting vehicle ids end point
|
15
|
-
PATH =
|
20
|
+
PATH = proc { |id| "/vehicles/#{id}" }
|
16
21
|
|
17
22
|
attr_reader :id
|
18
23
|
|
19
24
|
def initialize(token:, id:, unit_system: IMPERIAL, version: Smartcar.get_api_version)
|
25
|
+
super
|
20
26
|
raise InvalidParameterValue.new, "Invalid Units provided : #{unit_system}" unless UNITS.include?(unit_system)
|
21
|
-
raise InvalidParameterValue.new,
|
22
|
-
raise InvalidParameterValue.new,
|
27
|
+
raise InvalidParameterValue.new, 'Vehicle ID (id) is a required field' if id.nil?
|
28
|
+
raise InvalidParameterValue.new, 'Access Token(token) is a required field' if token.nil?
|
29
|
+
|
23
30
|
@token = token
|
24
31
|
@id = id
|
25
32
|
@unit_system = unit_system
|
@@ -33,7 +40,7 @@ module Smartcar
|
|
33
40
|
#
|
34
41
|
# @return [Array] of vehicle IDs(Strings)
|
35
42
|
def self.all_vehicle_ids(token:, options: {}, version: Smartcar.get_api_version)
|
36
|
-
response,
|
43
|
+
response, = new(token: token, id: 'none', version: version).fetch(
|
37
44
|
path: PATH.call(''),
|
38
45
|
options: options
|
39
46
|
)
|
@@ -50,10 +57,11 @@ module Smartcar
|
|
50
57
|
#
|
51
58
|
# @return [Boolean] true or false
|
52
59
|
def self.compatible?(vin:, scope:, country: 'US', version: Smartcar.get_api_version)
|
53
|
-
raise InvalidParameterValue.new,
|
54
|
-
raise InvalidParameterValue.new,
|
60
|
+
raise InvalidParameterValue.new, 'vin is a required field' if vin.nil?
|
61
|
+
raise InvalidParameterValue.new, 'scope is a required field' if scope.nil?
|
55
62
|
|
56
|
-
response,
|
63
|
+
response, = new(token: 'none', id: 'none', version: version).fetch(
|
64
|
+
path: COMPATIBLITY_PATH,
|
57
65
|
options: {
|
58
66
|
vin: vin,
|
59
67
|
scope: scope.join(' '),
|
@@ -64,241 +72,10 @@ module Smartcar
|
|
64
72
|
response['compatible']
|
65
73
|
end
|
66
74
|
|
67
|
-
# Method to get batch requests
|
68
|
-
# API - https://smartcar.com/docs/api#post-batch-request
|
69
|
-
# @param attributes [Array] Array of strings or symbols of attributes to be fetched together
|
70
|
-
#
|
71
|
-
# @return [Hash] Hash wth key as requested attribute(symbol) and value as Error OR Object of the requested attribute
|
72
|
-
def batch(attributes = [])
|
73
|
-
raise InvalidParameterValue.new, "vin is a required field" if attributes.nil?
|
74
|
-
request_body = get_batch_request_body(attributes)
|
75
|
-
response, _meta = post(PATH.call(id) + "/batch", request_body)
|
76
|
-
process_batch_response(response)
|
77
|
-
end
|
78
|
-
|
79
|
-
# Fetch the list of permissions that this application has been granted for
|
80
|
-
# this vehicle
|
81
|
-
# EX : Smartcar::Vehicle.new(token: token, id: id).permissions
|
82
|
-
# @param options [Hash] - Optional filter parameters (check documentation)
|
83
|
-
#
|
84
|
-
# @return [Permissions] object
|
85
|
-
def permissions(options: {})
|
86
|
-
get_attribute(Permissions)
|
87
|
-
end
|
88
|
-
|
89
|
-
# Method Used toRevoke access for the current requesting application
|
90
|
-
# API - https://smartcar.com/docs/api#delete-disconnect
|
91
|
-
#
|
92
|
-
# @return [Boolean] true if success
|
93
|
-
def disconnect!
|
94
|
-
response = delete(PATH.call(id) + "/application")
|
95
|
-
response['status'] == SUCCESS
|
96
|
-
end
|
97
|
-
|
98
|
-
# Methods Used to lock car
|
99
|
-
# API - https://smartcar.com/docs/api#post-security
|
100
|
-
#
|
101
|
-
# @return [Boolean] true if success
|
102
|
-
def lock!
|
103
|
-
lock_or_unlock!(action: Smartcar::LOCK)
|
104
|
-
end
|
105
|
-
|
106
|
-
# Methods Used to unlock car
|
107
|
-
# API - https://smartcar.com/docs/api#post-security
|
108
|
-
#
|
109
|
-
# @return [Boolean] true if success
|
110
|
-
def unlock!
|
111
|
-
lock_or_unlock!(action: Smartcar::UNLOCK)
|
112
|
-
end
|
113
|
-
|
114
|
-
# Method used to start charging a car
|
115
|
-
#
|
116
|
-
#
|
117
|
-
# @return [Boolean] true if success
|
118
|
-
def start_charge!
|
119
|
-
start_or_stop_charge!(action: Smartcar::START_CHARGE)
|
120
|
-
end
|
121
|
-
|
122
|
-
# Method used to stop charging a car
|
123
|
-
#
|
124
|
-
#
|
125
|
-
# @return [Boolean] true if success
|
126
|
-
def stop_charge!
|
127
|
-
start_or_stop_charge!(action: Smartcar::STOP_CHARGE)
|
128
|
-
end
|
129
|
-
|
130
|
-
# Returns make model year and id of the vehicle
|
131
|
-
# API - https://smartcar.com/api#get-vehicle-attributes
|
132
|
-
#
|
133
|
-
# @return [VehicleAttributes] object
|
134
|
-
def vehicle_attributes
|
135
|
-
get_attribute(VehicleAttributes)
|
136
|
-
end
|
137
|
-
|
138
|
-
# Returns the state of charge (SOC) and remaining range of an electric or
|
139
|
-
# plug-in hybrid vehicle's battery.
|
140
|
-
# API - https://smartcar.com/docs/api#get-ev-battery
|
141
|
-
#
|
142
|
-
# @return [Battery] object
|
143
|
-
def battery
|
144
|
-
get_attribute(Battery)
|
145
|
-
end
|
146
|
-
|
147
|
-
# Returns the capacity of an electric or
|
148
|
-
# plug-in hybrid vehicle's battery.
|
149
|
-
# API - https://smartcar.com/docs/api#get-ev-battery-capacity
|
150
|
-
#
|
151
|
-
# @return [Battery] object
|
152
|
-
def battery_capacity
|
153
|
-
get_attribute(BatteryCapacity)
|
154
|
-
end
|
155
|
-
|
156
|
-
# Returns the current charge status of the vehicle.
|
157
|
-
# API - https://smartcar.com/docs/api#get-ev-battery
|
158
|
-
#
|
159
|
-
# @return [Charge] object
|
160
|
-
def charge
|
161
|
-
get_attribute(Charge)
|
162
|
-
end
|
163
|
-
|
164
|
-
# Returns the remaining life span of a vehicle's engine oil
|
165
|
-
# API - https://smartcar.com/docs/api#get-engine-oil-life
|
166
|
-
#
|
167
|
-
# @return [EngineOil] object
|
168
|
-
def engine_oil
|
169
|
-
get_attribute(EngineOil)
|
170
|
-
end
|
171
|
-
|
172
|
-
# Returns the status of the fuel remaining in the vehicle's gas tank.
|
173
|
-
# API - https://smartcar.com/docs/api#get-fuel-tank
|
174
|
-
#
|
175
|
-
# @return [Fuel] object
|
176
|
-
def fuel
|
177
|
-
get_attribute(Fuel)
|
178
|
-
end
|
179
|
-
|
180
|
-
# Returns the last known location of the vehicle in geographic coordinates.
|
181
|
-
# API - https://smartcar.com/docs/api#get-location
|
182
|
-
#
|
183
|
-
# @return [Location] object
|
184
|
-
def location
|
185
|
-
get_attribute(Location)
|
186
|
-
end
|
187
|
-
|
188
|
-
# Returns the vehicle's last known odometer reading.
|
189
|
-
# API - https://smartcar.com/docs/api#get-odometer
|
190
|
-
#
|
191
|
-
# @return [Odometer] object
|
192
|
-
def odometer
|
193
|
-
get_attribute(Odometer)
|
194
|
-
end
|
195
|
-
|
196
|
-
# Returns the air pressure of each of the vehicle's tires.
|
197
|
-
# API - https://smartcar.com/docs/api#get-tire-pressure
|
198
|
-
#
|
199
|
-
# @return [TirePressure] object
|
200
|
-
def tire_pressure
|
201
|
-
get_attribute(TirePressure)
|
202
|
-
end
|
203
|
-
|
204
|
-
# Returns the vehicle's manufacturer identifier (VIN).
|
205
|
-
# API - https://smartcar.com/docs/api#get-vin
|
206
|
-
#
|
207
|
-
# @return [String] Vin of the vehicle.
|
208
|
-
def vin
|
209
|
-
_object = get_attribute(Vin)
|
210
|
-
@vin ||= _object.vin
|
211
|
-
end
|
212
|
-
|
213
75
|
private
|
214
76
|
|
215
|
-
def allowed_attributes
|
216
|
-
@allowed_attributes ||= {
|
217
|
-
battery: get_path(Battery),
|
218
|
-
charge: get_path(Charge),
|
219
|
-
engine_oil: get_path(EngineOil),
|
220
|
-
fuel: get_path(Fuel),
|
221
|
-
location: get_path(Location),
|
222
|
-
odometer: get_path(Odometer),
|
223
|
-
permissions: get_path(Permissions),
|
224
|
-
tire_pressure: get_path(TirePressure),
|
225
|
-
vin: get_path(Vin),
|
226
|
-
}
|
227
|
-
end
|
228
|
-
|
229
|
-
def path_to_class
|
230
|
-
@path_to_class ||= {
|
231
|
-
get_path(Battery) => Battery,
|
232
|
-
get_path(Charge) => Charge,
|
233
|
-
get_path(EngineOil) => EngineOil,
|
234
|
-
get_path(Fuel) => Fuel,
|
235
|
-
get_path(Location) => Location,
|
236
|
-
get_path(Odometer) => Odometer,
|
237
|
-
get_path(Permissions) => Permissions,
|
238
|
-
get_path(TirePressure) => TirePressure,
|
239
|
-
get_path(Vin) => Vin,
|
240
|
-
}
|
241
|
-
end
|
242
|
-
|
243
|
-
# @private
|
244
|
-
BatchItemResponse = Struct.new(:body, :status, :headers) do
|
245
|
-
def body_with_meta
|
246
|
-
body.merge(meta: headers)
|
247
|
-
end
|
248
|
-
end
|
249
|
-
|
250
|
-
def get_batch_request_body(attributes)
|
251
|
-
attributes = validated_attributes(attributes)
|
252
|
-
requests = attributes.each_with_object([]) do |item, requests|
|
253
|
-
requests << { path: allowed_attributes[item] }
|
254
|
-
end
|
255
|
-
{ requests: requests }
|
256
|
-
end
|
257
|
-
|
258
|
-
def process_batch_response(responses)
|
259
|
-
inverted_map = allowed_attributes.invert
|
260
|
-
responses["responses"].each_with_object({}) do |response, result|
|
261
|
-
item_response = BatchItemResponse.new(response["body"], response["code"], response["headers"])
|
262
|
-
error = get_error(item_response)
|
263
|
-
path = response["path"]
|
264
|
-
result[inverted_map[path]] = error || get_object(path_to_class[path], item_response.body_with_meta)
|
265
|
-
end
|
266
|
-
end
|
267
|
-
|
268
|
-
def validated_attributes(attributes)
|
269
|
-
attributes.map!(&:to_sym)
|
270
|
-
unsupported_attributes = (attributes - allowed_attributes.keys) || []
|
271
|
-
unless unsupported_attributes.empty?
|
272
|
-
message = "Unsupported attribute(s) requested in batch - #{unsupported_attributes.join(',')}"
|
273
|
-
raise InvalidParameterValue.new, message
|
274
|
-
end
|
275
|
-
attributes
|
276
|
-
end
|
277
|
-
|
278
|
-
def get_attribute(klass)
|
279
|
-
body, meta = fetch(
|
280
|
-
path: klass::PATH.call(id)
|
281
|
-
)
|
282
|
-
get_object(klass, body.merge(meta: meta))
|
283
|
-
end
|
284
|
-
|
285
77
|
def get_object(klass, data)
|
286
78
|
klass.new(data)
|
287
79
|
end
|
288
|
-
|
289
|
-
def get_path(klass)
|
290
|
-
path = klass::PATH.call(id)
|
291
|
-
path.split("/vehicles/#{id}").last
|
292
|
-
end
|
293
|
-
|
294
|
-
def lock_or_unlock!(action:)
|
295
|
-
response, meta = post(PATH.call(id) + "/security", { action: action })
|
296
|
-
response['status'] == SUCCESS
|
297
|
-
end
|
298
|
-
|
299
|
-
def start_or_stop_charge!(action:)
|
300
|
-
response, meta = post(PATH.call(id) + "/charge", { action: action })
|
301
|
-
response['status'] == SUCCESS
|
302
|
-
end
|
303
80
|
end
|
304
81
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Smartcar
|
2
4
|
# class to represent Vehicle attributes like make model year
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
5
|
+
# @attr [String] id Smartcar vehicle ID
|
6
|
+
# @attr [String] make Manufacturer of the vehicle.
|
7
|
+
# @attr [String] model Model of the vehicle.
|
8
|
+
# @attr [Number] year Model year of the vehicle.
|
7
9
|
class VehicleAttributes < Base
|
8
10
|
# Path Proc for hitting vehicle attributes end point
|
9
|
-
PATH =
|
11
|
+
PATH = proc { |id| "/vehicles/#{id}" }
|
10
12
|
attr_accessor :id, :make, :model, :year
|
11
13
|
end
|
12
14
|
end
|