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.
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Smartcar
2
4
  # class to represent Odometer
3
- #@attr [Number] distanceLast recorded odometer reading.
5
+ # @attr [Number] distanceLast recorded odometer reading.
4
6
  class Odometer < Base
5
7
  # Path Proc for hitting odometer end point
6
- PATH = Proc.new{|id| "/vehicles/#{id}/odometer"}
8
+ PATH = proc { |id| "/vehicles/#{id}/odometer" }
7
9
  attr_reader :distance
8
10
  end
9
11
  end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Smartcar
2
4
  # class to represent permissions response
3
- #@attr [Array] permissions Array of permissions granted on the vehicle.
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 = Proc.new{|id| "/vehicles/#{id}/permissions"}
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
- #@attr [Number] back_left Last recorded tire pressure of the back left tire.
4
- #@attr [Number] back_right Last recorded tire pressure of the back right tire.
5
- #@attr [Number] front_left Last recorded tire pressure of the front left tire.
6
- #@attr [Number] front_right Last recorded tire pressure of the front right tire.
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 = Proc.new{|id| "/vehicles/#{id}/tires/pressure"}
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
- alias_method :back_left, :backLeft
15
- alias_method :back_right, :backRight
16
- alias_method :front_left, :frontLeft
17
- alias_method :front_right, :frontRight
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
- #@attr [String] id Smartcar user id.
4
- #@attr [String] token Access token used to connect to Smartcar API.
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'.freeze
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 "[DEPRECATION] `Smartcar::User.user_id` is deprecated and will be removed in next major version update. Please use `Smartcar::User.get` instead."
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
 
@@ -1,5 +1,7 @@
1
- # Utils module , provides utility methods to underlying classes
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("@").to_sym] = instance_variable_get(attribute)
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("Authentication error") if status == 401
43
- return Smartcar::ExternalServiceError.new("API error - #{response.body}")
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
@@ -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
- #@attr [String] token Access token used to connect to Smartcar API.
8
- #@attr [String] id Smartcar vehicle ID.
9
- #@attr [String] unit_system unit system to represent the data in.
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'.freeze
17
+ COMPATIBLITY_PATH = '/compatibility'
13
18
 
14
19
  # Path for hitting vehicle ids end point
15
- PATH = Proc.new{|id| "/vehicles/#{id}"}
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, "Vehicle ID (id) is a required field" if id.nil?
22
- raise InvalidParameterValue.new, "Access Token(token) is a required field" if token.nil?
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, meta = new(token: token, id: 'none', version: version).fetch(
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, "vin is a required field" if vin.nil?
54
- raise InvalidParameterValue.new, "scope is a required field" if scope.nil?
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, meta = new(token: 'none', id: 'none', version: version).fetch(path: COMPATIBLITY_PATH,
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
- #@attr [String] id Smartcar vehicle ID
4
- #@attr [String] make Manufacturer of the vehicle.
5
- #@attr [String] model Model of the vehicle.
6
- #@attr [Number] year Model year of the vehicle.
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 = Proc.new{|id| "/vehicles/#{id}"}
11
+ PATH = proc { |id| "/vehicles/#{id}" }
10
12
  attr_accessor :id, :make, :model, :year
11
13
  end
12
14
  end