tesla_api 2.0.0 → 3.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +5 -2
- data/Rakefile +1 -1
- data/docs/vehicle/optioncodes.md +54 -26
- data/lib/tesla_api.rb +7 -2
- data/lib/tesla_api/autopark.rb +8 -10
- data/lib/tesla_api/client.rb +50 -51
- data/lib/tesla_api/stream.rb +28 -21
- data/lib/tesla_api/vehicle.rb +9 -9
- data/lib/tesla_api/version.rb +1 -1
- data/spec/lib/tesla_api/client_spec.rb +1 -10
- data/tesla_api.gemspec +2 -2
- metadata +5 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 310c9a551e9ace78ebf8eeee97d301ef30421545f0c0a876532653bad401d00f
|
4
|
+
data.tar.gz: 01344c140bec766dd95697124888b9b860d8a1a3028811d64ec41e15ff5f4adf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7b5c85dfc21d90bb311b8818d636d2e320aff0ca5fd5da3d6a99046c717dd91cd7b0d1ba0404d130aec49f55904442776cf1df3b78e3dfd5661aa6f92c92bfbd
|
7
|
+
data.tar.gz: 8f5bf9d04e7ee75980510f5705ecc8d1530086798a858c9a65744ac2eeb346173bbaa290898dd649c1e666e4f2b6df2f92a533f059e7f60adcbaf82afd9cb0e6
|
data/README.md
CHANGED
@@ -36,8 +36,11 @@ Here's a quick example:
|
|
36
36
|
```ruby
|
37
37
|
require 'tesla_api'
|
38
38
|
|
39
|
-
tesla_api = TeslaApi::Client.new(email, client_id, client_secret)
|
40
|
-
tesla_api.login!(password)
|
39
|
+
tesla_api = TeslaApi::Client.new(email: email, client_id: client_id, client_secret: client_secret)
|
40
|
+
tesla_api.login!(password)
|
41
|
+
# Or if you have an access token:
|
42
|
+
tesla_api = TeslaApi::Client.new(access_token: access_token)
|
43
|
+
|
41
44
|
model_s = tesla_api.vehicles.first # => <TeslaApi::Vehicle>
|
42
45
|
|
43
46
|
model_s.wake_up
|
data/Rakefile
CHANGED
data/docs/vehicle/optioncodes.md
CHANGED
@@ -30,7 +30,7 @@ appreciated!_
|
|
30
30
|
| AD09 | Adapter, Swiss (1 phase, 10A) | |
|
31
31
|
| AD10 | Adapter, Denmark (1 phase, 13A) | |
|
32
32
|
| AD11 | Adapter, Italy (1 phase, 13A) | |
|
33
|
-
| AD15 |
|
33
|
+
| AD15 | Adapter | J1772 |
|
34
34
|
| ADPX2 | Type 2 Public Charging Connector | |
|
35
35
|
| ADX4 | No European 3-Phase | |
|
36
36
|
| ADX5 | European 3-Phase, IT | |
|
@@ -38,7 +38,7 @@ appreciated!_
|
|
38
38
|
| ADX7 | No - 3-ph Red IEC309 (3 phase, 16A) | |
|
39
39
|
| ADX9 | No - Adapter, Swiss (1 phase, 10A) | |
|
40
40
|
| ADX8 | Blue IEC309 (1 phase, 230V 32A) | |
|
41
|
-
| AF00 | No HEPA Filter | |
|
41
|
+
| AF00 | No HEPA Filter | Standard air filter, no air ionizer |
|
42
42
|
| AF02 | HEPA Filter | |
|
43
43
|
| AH00 | No Accessory Hitch | |
|
44
44
|
| APE1 | Enhanced Autopilot | |
|
@@ -55,17 +55,19 @@ appreciated!_
|
|
55
55
|
| APPB | Enhanced Autopilot | |
|
56
56
|
| AU00 | No Audio Package | |
|
57
57
|
| AU01 | Ultra High Fidelity Sound | |
|
58
|
+
| AU3P | Sound Studio Package | Premium audio package |
|
58
59
|
| BC0B | Black Brake Calipers | |
|
59
60
|
| BC0R | Red Brake Calipers | |
|
60
61
|
| BC3B | Black Brake Calipers, Model 3 | |
|
61
62
|
| BCMB | Black Brake Calipers | |
|
62
63
|
| BCYR | Performance Brakes | |
|
64
|
+
| BG30 | No Badge | Model 3 |
|
63
65
|
| BP00 | No Ludicrous | |
|
64
66
|
| BP01 | Ludicrous Speed Upgrade | |
|
65
67
|
| BR00 | No Battery Firmware Limit | |
|
66
68
|
| BR03 | Battery Firmware Limit (60kWh) | |
|
67
69
|
| BR05 | Battery Firmware Limit (75kWh) | |
|
68
|
-
| BS00 |
|
70
|
+
| BS00 | Blind Spot Sensor Package | |
|
69
71
|
| BS01 | Special Production Flag | |
|
70
72
|
| BT37 | 75 kWh (Model 3) | |
|
71
73
|
| BT40 | 40 kWh | |
|
@@ -85,7 +87,7 @@ appreciated!_
|
|
85
87
|
| CF00 | High Power Charger | |
|
86
88
|
| CF01 | 48amp charger | |
|
87
89
|
| CH00 | Standard Charger (40 Amp) | |
|
88
|
-
| CH01 | Dual Chargers (80 Amp) | |
|
90
|
+
| CH01 | Dual Chargers (80 Amp) | Twin 10kW charge config |
|
89
91
|
| CH04 | 72 Amp Charger (Model S/X) | |
|
90
92
|
| CH05 | 48 Amp Charger (Model S/X) | |
|
91
93
|
| CH07 | 48 Amp Charger (Model 3) | |
|
@@ -96,32 +98,38 @@ appreciated!_
|
|
96
98
|
| COUS | Country: United States | |
|
97
99
|
| CONL | Country: Netherlands | |
|
98
100
|
| CPW1 | 20" Performance Wheels | |
|
99
|
-
| CW00 | No Cold Weather Package |
|
100
|
-
| CW02 | Subzero Weather Package |
|
101
|
+
| CW00 | Weather Package | No Cold Weather Package |
|
102
|
+
| CW02 | Weather Package | Subzero Weather Package |
|
101
103
|
| DA00 | No Autopilot | |
|
102
|
-
| DA01 | Active Safety (ACC,LDW,SA) | |
|
104
|
+
| DA01 | Active Safety (ACC,LDW,SA) | Drivers Assistance Package |
|
103
105
|
| DA02 | Autopilot Convenience Features | |
|
104
106
|
| DCF0 | Autopilot Convenience Features (DCF0) | |
|
105
107
|
| DRLH | Left Hand Drive | |
|
106
108
|
| BC3R | Performance Brakes | Model 3 |
|
107
109
|
| DRRH | Right Hand Drive | |
|
108
|
-
| DSH5 | PUR
|
110
|
+
| DSH5 | Dashboard | PUR Dashboard Pad |
|
109
111
|
| DSH7 | Alcantara Dashboard Accents | |
|
110
112
|
| DSHG | PUR Dash Pad | |
|
111
113
|
| DU00 | Drive Unit - IR | |
|
112
114
|
| DU01 | Drive Unit - Infineon | |
|
113
115
|
| DV2W | Rear-Wheel Drive | |
|
114
116
|
| DV4W | All-Wheel Drive | |
|
117
|
+
| FC3P | Front Console Front Console (Premium) | Model 3 |
|
115
118
|
| FG00 | No Exterior Lighting Package | |
|
116
|
-
| FG01 | Exterior Lighting Package |
|
117
|
-
| FG02 |
|
119
|
+
| FG01 | Fog Lamps | Exterior Lighting Package |
|
120
|
+
| FG02 | Fog Lamps | Fog Lamps |
|
121
|
+
| FG31 | Fog Lamps | Premium Fog Lights (Model 3) |
|
122
|
+
| FM3B | Performance Package (Model 3) | |
|
118
123
|
| FMP6 | FMP6 | |
|
119
124
|
| FR01 | Base Front Row | |
|
120
125
|
| FR02 | Ventilated Front Seats | |
|
121
126
|
| FR03 | FR03 | |
|
122
127
|
| FR04 | FR04 | |
|
128
|
+
| GLFR | Assembly | Final Assembly Fremont |
|
123
129
|
| HC00 | No Home Charging installation | |
|
124
130
|
| HC01 | Home Charging Installation | |
|
131
|
+
| HM31 | Teck Package - Homelink | Homelink |
|
132
|
+
| HL31 | Head Lamp (Model 3) | Uplevel Headlamps |
|
125
133
|
| HP00 | No HPWC Ordered | |
|
126
134
|
| HP01 | HPWC Ordered | |
|
127
135
|
| ID3W | (Model 3) Wood Decor | |
|
@@ -132,7 +140,7 @@ appreciated!_
|
|
132
140
|
| IDOM | Matte Obeche Wood Decor | |
|
133
141
|
| IDOG | Gloss Obeche Wood Decor | |
|
134
142
|
| IDLW | Lacewood Decor | |
|
135
|
-
| IDPB | Piano Black Decor | |
|
143
|
+
| IDPB | Piano Black Decor | |
|
136
144
|
| IN3BB | All Black Partial Premium Interior | |
|
137
145
|
| IN3PB | All Black Premium Interior | |
|
138
146
|
| INBBW | White | |
|
@@ -145,6 +153,7 @@ appreciated!_
|
|
145
153
|
| INWPT | Tan Interior | |
|
146
154
|
| INYPB | All Black Premium Interior | |
|
147
155
|
| INYPW | Black and White Premium Interior | |
|
156
|
+
| IL31 | Interior Ambient Lighting | |
|
148
157
|
| IVBPP | All Black Interior | |
|
149
158
|
| IVBSW | Ultra White Interior | |
|
150
159
|
| IVBTB | All Black Interior | |
|
@@ -153,10 +162,11 @@ appreciated!_
|
|
153
162
|
| IX01 | Extended Nappa Leather Trim | |
|
154
163
|
| LLP1 | LLP1 | |
|
155
164
|
| LLP2 | LLP2 | |
|
156
|
-
|
|
165
|
+
| LP00 | Lighting Package | No Lighting Package |
|
166
|
+
| LP01 | Lighting Package | Premium Interior Lighting |
|
157
167
|
| LT00 | Vegan interior | |
|
158
168
|
| LT01 | Standard interior | |
|
159
|
-
| LT1B |
|
169
|
+
| LT1B | Lower Trim | Lower Trim |
|
160
170
|
| LT3W | LT3W | |
|
161
171
|
| LT4B | LT4B | |
|
162
172
|
| LT4C | LT4C | |
|
@@ -166,11 +176,13 @@ appreciated!_
|
|
166
176
|
| LT6P | LT6P | |
|
167
177
|
| LTPB | Lower Trim PUR Black | |
|
168
178
|
| ME01 | Memory Seats | |
|
169
|
-
| ME02 | Memory
|
179
|
+
| ME02 | Seat Memory | Seat Memory LHD Driver |
|
170
180
|
| MI00 | 2015 Production Refresh | |
|
181
|
+
| MI00 | Project/Program Code M3 | Base Manufacturing Intro Code |
|
171
182
|
| MI01 | 2016 Production Refresh | |
|
172
183
|
| MI02 | 2017 Production Refresh | |
|
173
184
|
| MI03 | 201? Production Refresh | Found on Model X ordered 11/2018 delivered 3/2019 |
|
185
|
+
| MR31 | Tech Package - Mirror -YES | Uplevel Mirrors |
|
174
186
|
| MT300 | Standard Range Rear-Wheel Drive | |
|
175
187
|
| MT301 | Standard Range Plus Rear-Wheel Drive | |
|
176
188
|
| MT302 | Long Range Rear-Wheel Drive | |
|
@@ -192,7 +204,7 @@ appreciated!_
|
|
192
204
|
| PF01 | Performance Legacy Package | |
|
193
205
|
| PI00 | No Premium Interior | |
|
194
206
|
| PI01 | Premium Upgrades Package | |
|
195
|
-
| PK00 |
|
207
|
+
| PK00 | Parking Sensors | |
|
196
208
|
| PMAB | Anza Brown Metallic Color | |
|
197
209
|
| PMBL | Obsidian Black Multi-Coat Color | |
|
198
210
|
| PMMB | Monterey Blue Metallic Color | |
|
@@ -206,6 +218,7 @@ appreciated!_
|
|
206
218
|
| PPSR | Signature Red Color | |
|
207
219
|
| PPSW | Pearl White Multi-Coat Color | |
|
208
220
|
| PPTI | Titanium Metallic Color | |
|
221
|
+
| PL30 | No Aluminum Pedal | |
|
209
222
|
| PL31 | Performance Pedals | Model 3 |
|
210
223
|
| PRM30 | Partial Premium Interior | |
|
211
224
|
| PRM31 | Premium Interior | |
|
@@ -213,6 +226,7 @@ appreciated!_
|
|
213
226
|
| PRMY1 | Premium Interior | |
|
214
227
|
| PS00 | No Parcel Shelf | |
|
215
228
|
| PS01 | Parcel Shelf | |
|
229
|
+
| RS3H | Second Row Seat Rear Seats (Heated) | Model 3 |
|
216
230
|
| PX00 | No Performance Plus Package | |
|
217
231
|
| PX01 | Performance Plus | |
|
218
232
|
| PX6D | Zero to 60 in 2.5 sec | |
|
@@ -242,32 +256,40 @@ appreciated!_
|
|
242
256
|
| RCX0 | No Rear Console | |
|
243
257
|
| RF3G | Model 3 Glass Roof | |
|
244
258
|
| RFBK | Black Roof | |
|
245
|
-
| RFBC | Body Color Roof | |
|
259
|
+
| RFBC | Body Color Roof | Roof |
|
246
260
|
| RFFG | Glass Roof | |
|
247
261
|
| RFP0 | All Glass Panoramic Roof | |
|
248
262
|
| RFP2 | Sunroof | |
|
249
263
|
| RFPX | Model X Roof | |
|
264
|
+
| S02B | Seat | BLK Leather |
|
250
265
|
| S02P | S02P | |
|
251
266
|
| S31B | S31B | |
|
252
267
|
| S32C | S32C | |
|
253
268
|
| S32P | S32P | |
|
254
269
|
| S32W | S32W | |
|
270
|
+
| S3PB | Seat Black PUR Premium Seats | |
|
255
271
|
| SC00 | No Supercharging | |
|
256
272
|
| SC01 | Supercharging Enabled | |
|
257
273
|
| SC04 | Pay Per Use Supercharging | |
|
258
274
|
| SC05 | Free Supercharging | |
|
275
|
+
| SLR0 | No Rear Spoiler | |
|
259
276
|
| SP00 | No Security Package | |
|
260
|
-
| SR01 | Standard 2nd row | |
|
277
|
+
| SR01 | Standard 2nd row | Second Row Seat |
|
261
278
|
| SR06 | Seven Seat Interior | |
|
262
279
|
| SR07 | Standard 2nd row | |
|
263
280
|
| ST00 | Non-leather Steering Wheel | |
|
264
281
|
| ST01 | Non-heated Leather Steering Wheel | |
|
282
|
+
| ST31 | Steering Wheel | Premium Steering Wheel |
|
283
|
+
| STCP | Steering Wheel | Steering Column (Power) |
|
265
284
|
| STY5S | Five Seat Interior | |
|
266
285
|
| STY7S | Seven Seat Interior | |
|
267
286
|
| SU00 | Standard Suspension | |
|
268
287
|
| SU01 | Smart Air Suspension | |
|
269
|
-
|
|
270
|
-
|
|
288
|
+
| SU3C | Suspension | Coil spring suspension |
|
289
|
+
| T3MA | Tires M3 | 18 Michelin All Season, Square |
|
290
|
+
| TIC4 | Tires | All-Season Tires |
|
291
|
+
| TIMP | Tires | Michelin Primacy 19" Tire |
|
292
|
+
| TM00 | Model Trim | General Production Series Vehicle |
|
271
293
|
| TM02 | General Production Signature Trim | |
|
272
294
|
| TM0A | ALPHA PRE-PRODUCTION NON-SALEABLE | |
|
273
295
|
| TM0B | BETA PRE-PRODUCTION NON-SALEABLE | |
|
@@ -275,22 +297,28 @@ appreciated!_
|
|
275
297
|
| TP01 | Tech Package - No Autopilot | |
|
276
298
|
| TP02 | Tech Package with Autopilot | |
|
277
299
|
| TP03 | Tech Package with Enhanced Autopilot | |
|
278
|
-
| TR00 | No
|
300
|
+
| TR00 | No Rear Facing Seats |
|
279
301
|
| TR01 | Third Row Seating | |
|
280
302
|
| TRA1 | Third Row HVAC | |
|
281
|
-
|
|
303
|
+
| TW00 | No Tow Package | |
|
304
|
+
| TW01 | Tow Package | |
|
282
305
|
| UM01 | Universal Mobile Charger - US Port (Single) | |
|
306
|
+
| UT3P | Suede Grey Premium Headliner | |
|
283
307
|
| UTAB | Black Alcantara Headliner | |
|
284
308
|
| UTAW | Light Headliner | |
|
309
|
+
| UTMF | Headliner | |
|
285
310
|
| UTPB | Dark Headliner | |
|
286
311
|
| UTSB | Dark Headliner | |
|
287
312
|
| UTZW | Light Headliner | |
|
313
|
+
| USSB | Safety | Safety US Black |
|
288
314
|
| SLR1 | Carbon Fibre Spoiler | Model 3 |
|
289
315
|
| SPT31 | Performance Upgrade | Model 3 |
|
290
316
|
| SPTY1 | Performance Upgrade | Model Y |
|
291
317
|
| W32P | 20" Performance Wheels | Model 3 |
|
292
318
|
| W38B | 18" Aero Wheels | For the Model 3 and Model Y |
|
293
319
|
| W39B | 19" Sport Wheels | |
|
320
|
+
| WR00 | No Wrap | |
|
321
|
+
| WT19 | 19" Wheels | |
|
294
322
|
| WT20 | 20" Silver Slipstream Wheels | |
|
295
323
|
| WT22 | 22" Silver Turbine Wheels | |
|
296
324
|
| WTAB | 21" Black Arachnid Wheels | |
|
@@ -338,14 +366,14 @@ appreciated!_
|
|
338
366
|
| X014 | Override: No Satellite Radio | |
|
339
367
|
| X019 | Carbon Fiber Spoiler | |
|
340
368
|
| X020 | No Performance Exterior | |
|
341
|
-
| X021 | No Spoiler | |
|
369
|
+
| X021 | No Rear Carbon Fiber Spoiler | |
|
342
370
|
| X024 | Performance Package | |
|
343
|
-
| X025 |
|
344
|
-
| X027 | Lighted Door Handles | |
|
345
|
-
| X028 | Battery Badge | |
|
371
|
+
| X025 | Performance Powertrain | |
|
372
|
+
| X027 | Lighted Door Handles | Light handle |
|
373
|
+
| X028 | Battery Badge | Normal Badging |
|
346
374
|
| X029 | Remove Battery Badge | |
|
347
375
|
| X030 | Override: No Passive Entry Pkg | |
|
348
|
-
| X031 | Keyless Entry | |
|
376
|
+
| X031 | Keyless Entry | Passive Entry Pkg |
|
349
377
|
| X037 | Powerfolding Mirrors | |
|
350
378
|
| X039 | DAB Radio | |
|
351
379
|
| X040 | No DAB Radio | |
|
data/lib/tesla_api.rb
CHANGED
data/lib/tesla_api/autopark.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
require 'faye/websocket'
|
2
|
-
|
3
1
|
module TeslaApi
|
4
2
|
module Autopark
|
5
3
|
def start_autopark(&handler)
|
6
4
|
EventMachine.run do
|
7
|
-
|
5
|
+
autopark_socket.on(:message) do |event|
|
8
6
|
message = if event.data.is_a?(Array)
|
9
7
|
JSON.parse(event.data.map(&:chr).join)
|
10
8
|
else
|
@@ -15,8 +13,8 @@ module TeslaApi
|
|
15
13
|
handler.call(message.delete('msg_type'), message)
|
16
14
|
end
|
17
15
|
|
18
|
-
|
19
|
-
@
|
16
|
+
autopark_socket.on(:close) do |_|
|
17
|
+
@autopark_socket = nil
|
20
18
|
@heartbeat && @heartbeat.cancel
|
21
19
|
EventMachine.stop
|
22
20
|
end
|
@@ -34,14 +32,14 @@ module TeslaApi
|
|
34
32
|
msg_type: 'autopark:heartbeat_app',
|
35
33
|
timestamp: Time.now.to_i
|
36
34
|
}
|
37
|
-
|
35
|
+
autopark_socket.send(beat.to_json)
|
38
36
|
end
|
39
37
|
end
|
40
38
|
end
|
41
39
|
|
42
|
-
def
|
43
|
-
@
|
44
|
-
|
40
|
+
def autopark_socket
|
41
|
+
@autopark_socket ||= Faye::WebSocket::Client.new(
|
42
|
+
autopark_socket_endpoint,
|
45
43
|
nil,
|
46
44
|
{
|
47
45
|
headers: {
|
@@ -55,7 +53,7 @@ module TeslaApi
|
|
55
53
|
Base64.strict_encode64("#{email}:#{self['tokens'].first}")
|
56
54
|
end
|
57
55
|
|
58
|
-
def
|
56
|
+
def autopark_socket_endpoint
|
59
57
|
"wss://streaming.vn.teslamotors.com/connect/#{self['vehicle_id']}"
|
60
58
|
end
|
61
59
|
end
|
data/lib/tesla_api/client.rb
CHANGED
@@ -1,12 +1,8 @@
|
|
1
1
|
module TeslaApi
|
2
2
|
class Client
|
3
|
-
|
4
|
-
base_uri 'https://owner-api.teslamotors.com/api/1'
|
5
|
-
headers 'User-Agent' => "github.com/timdorr/tesla-api v:#{VERSION}"
|
6
|
-
format :json
|
7
|
-
raise_on [401]
|
3
|
+
attr_reader :api, :email, :access_token, :access_token_expires_at, :refresh_token, :client_id, :client_secret
|
8
4
|
|
9
|
-
|
5
|
+
BASE_URI = 'https://owner-api.teslamotors.com/api/1'
|
10
6
|
|
11
7
|
def initialize(
|
12
8
|
email: nil,
|
@@ -21,59 +17,54 @@ module TeslaApi
|
|
21
17
|
@client_id = client_id
|
22
18
|
@client_secret = client_secret
|
23
19
|
|
24
|
-
self.update_token(
|
25
|
-
access_token: access_token,
|
26
|
-
access_token_expires_at: access_token_expires_at,
|
27
|
-
refresh_token: refresh_token
|
28
|
-
)
|
29
|
-
end
|
30
|
-
|
31
|
-
def update_token(access_token:, access_token_expires_at:, refresh_token:)
|
32
20
|
@access_token = access_token
|
33
21
|
@access_token_expires_at = access_token_expires_at
|
34
22
|
@refresh_token = refresh_token
|
35
|
-
self.class.headers 'Authorization' => "Bearer #{access_token}" if access_token
|
36
23
|
|
37
|
-
|
24
|
+
@api = Faraday.new(
|
25
|
+
BASE_URI,
|
26
|
+
headers: { 'User-Agent' => "github.com/timdorr/tesla-api v:#{VERSION}" }
|
27
|
+
) do |conn|
|
28
|
+
conn.request :json
|
29
|
+
conn.response :json
|
30
|
+
conn.response :raise_error
|
31
|
+
conn.adapter Faraday.default_adapter
|
32
|
+
end
|
38
33
|
end
|
39
34
|
|
40
35
|
def refresh_access_token
|
41
|
-
response =
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
refresh_token: response['refresh_token']
|
55
|
-
)
|
36
|
+
response = api.post(
|
37
|
+
'https://owner-api.teslamotors.com/oauth/token',
|
38
|
+
{
|
39
|
+
grant_type: 'refresh_token',
|
40
|
+
client_id: client_id,
|
41
|
+
client_secret: client_secret,
|
42
|
+
refresh_token: refresh_token
|
43
|
+
}
|
44
|
+
).body
|
45
|
+
|
46
|
+
@access_token = response['access_token']
|
47
|
+
@access_token_expires_at = Time.at(response['created_at'].to_f + response['expires_in'].to_f).to_datetime
|
48
|
+
@refresh_token = response['refresh_token']
|
56
49
|
|
57
50
|
response
|
58
51
|
end
|
59
52
|
|
60
53
|
def login!(password)
|
61
|
-
response =
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
)
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
refresh_token: response['refresh_token']
|
76
|
-
)
|
54
|
+
response = api.post(
|
55
|
+
'https://owner-api.teslamotors.com/oauth/token',
|
56
|
+
{
|
57
|
+
grant_type: 'password',
|
58
|
+
client_id: client_id,
|
59
|
+
client_secret: client_secret,
|
60
|
+
email: email,
|
61
|
+
password: password
|
62
|
+
}
|
63
|
+
).body
|
64
|
+
|
65
|
+
@access_token = response['access_token']
|
66
|
+
@access_token_expires_at = Time.at(response['created_at'].to_f + response['expires_in'].to_f).to_datetime
|
67
|
+
@refresh_token = response['refresh_token']
|
77
68
|
|
78
69
|
response
|
79
70
|
end
|
@@ -83,12 +74,20 @@ module TeslaApi
|
|
83
74
|
access_token_expires_at <= DateTime.now
|
84
75
|
end
|
85
76
|
|
86
|
-
def
|
87
|
-
|
77
|
+
def get(url)
|
78
|
+
api.get(url.sub(/^\//, ''), nil, { 'Authorization' => "Bearer #{access_token}" }).body
|
88
79
|
end
|
89
80
|
|
90
|
-
|
81
|
+
def post(url, body: nil)
|
82
|
+
api.post(url.sub(/^\//, ''), body, { 'Authorization' => "Bearer #{access_token}" }).body
|
83
|
+
end
|
91
84
|
|
92
|
-
|
85
|
+
def vehicles
|
86
|
+
get('/vehicles')['response'].map { |v| Vehicle.new(self, email, v['id'], v) }
|
87
|
+
end
|
88
|
+
|
89
|
+
def vehicle(id)
|
90
|
+
Vehicle.new(self, email, id, self.class.get("/vehicles/#{id}")['response'])
|
91
|
+
end
|
93
92
|
end
|
94
93
|
end
|
data/lib/tesla_api/stream.rb
CHANGED
@@ -2,10 +2,19 @@ module TeslaApi
|
|
2
2
|
module Stream
|
3
3
|
def stream(&receiver)
|
4
4
|
EventMachine.run do
|
5
|
-
|
6
|
-
attributes = chunk.split(",")
|
5
|
+
socket = create_streaming_socket
|
7
6
|
|
8
|
-
|
7
|
+
socket.on(:open) do |event|
|
8
|
+
socket.send(JSON.generate(stream_connect_message))
|
9
|
+
end
|
10
|
+
|
11
|
+
socket.on(:message) do |event|
|
12
|
+
data = JSON.parse(event.data.pack('c*'))
|
13
|
+
|
14
|
+
if data['msg_type'] == 'data:update'
|
15
|
+
attributes = data['value'].split(',')
|
16
|
+
|
17
|
+
receiver.call({
|
9
18
|
time: DateTime.strptime((attributes[0].to_i/1000).to_s, '%s'),
|
10
19
|
speed: attributes[1].to_f,
|
11
20
|
odometer: attributes[2].to_f,
|
@@ -19,35 +28,33 @@ module TeslaApi
|
|
19
28
|
range: attributes[10].to_f,
|
20
29
|
est_range: attributes[11].to_f,
|
21
30
|
heading: attributes[12].to_f
|
22
|
-
|
31
|
+
})
|
32
|
+
end
|
23
33
|
end
|
24
34
|
|
25
|
-
|
26
|
-
|
35
|
+
socket.on(:close) do |event|
|
36
|
+
EventMachine.stop
|
37
|
+
end
|
27
38
|
end
|
28
39
|
end
|
29
40
|
|
30
41
|
private
|
31
42
|
|
32
|
-
def
|
33
|
-
|
34
|
-
"#{stream_endpoint}/stream/#{self['vehicle_id']}/?values=#{stream_params}")
|
35
|
-
end
|
36
|
-
|
37
|
-
def http
|
38
|
-
request.get(
|
39
|
-
head: {
|
40
|
-
'authorization' => [email, self['tokens'].first]
|
41
|
-
},
|
42
|
-
inactivity_timeout: 15)
|
43
|
+
def create_streaming_socket
|
44
|
+
Faye::WebSocket::Client.new(streaming_endpoint)
|
43
45
|
end
|
44
46
|
|
45
|
-
def
|
46
|
-
'
|
47
|
+
def streaming_endpoint
|
48
|
+
'wss://streaming.vn.teslamotors.com/streaming/'
|
47
49
|
end
|
48
50
|
|
49
|
-
def
|
50
|
-
|
51
|
+
def stream_connect_message
|
52
|
+
{
|
53
|
+
msg_type: 'data:subscribe',
|
54
|
+
token: Base64.strict_encode64("#{email}:#{self['tokens'].first}"),
|
55
|
+
value: 'speed,odometer,soc,elevation,est_heading,est_lat,est_lng,power,shift_state,range,est_range,heading',
|
56
|
+
tag: self['vehicle_id'].to_s,
|
57
|
+
}
|
51
58
|
end
|
52
59
|
end
|
53
60
|
end
|
data/lib/tesla_api/vehicle.rb
CHANGED
@@ -2,10 +2,10 @@ module TeslaApi
|
|
2
2
|
class Vehicle
|
3
3
|
include Stream
|
4
4
|
include Autopark
|
5
|
-
attr_reader :api, :email, :id, :vehicle
|
5
|
+
attr_reader :client, :api, :email, :id, :vehicle
|
6
6
|
|
7
|
-
def initialize(
|
8
|
-
@
|
7
|
+
def initialize(client, email, id, vehicle)
|
8
|
+
@client = client
|
9
9
|
@email = email
|
10
10
|
@id = id
|
11
11
|
@vehicle = vehicle
|
@@ -28,15 +28,15 @@ module TeslaApi
|
|
28
28
|
# State
|
29
29
|
|
30
30
|
def data
|
31
|
-
|
31
|
+
client.get("/vehicles/#{id}/data")['response']
|
32
32
|
end
|
33
33
|
|
34
34
|
def mobile_enabled
|
35
|
-
|
35
|
+
client.get("/vehicles/#{id}/mobile_enabled")['response']
|
36
36
|
end
|
37
37
|
|
38
38
|
def nearby_charging_sites
|
39
|
-
|
39
|
+
client.get("/vehicles/#{id}/nearby_charging_sites")['response']
|
40
40
|
end
|
41
41
|
|
42
42
|
def gui_settings
|
@@ -62,7 +62,7 @@ module TeslaApi
|
|
62
62
|
# Commands
|
63
63
|
|
64
64
|
def wake_up
|
65
|
-
@vehicle =
|
65
|
+
@vehicle = client.post("/vehicles/#{id}/wake_up")['response']
|
66
66
|
end
|
67
67
|
|
68
68
|
def set_valet_mode(on, password=nil)
|
@@ -197,11 +197,11 @@ module TeslaApi
|
|
197
197
|
private
|
198
198
|
|
199
199
|
def data_request(name)
|
200
|
-
|
200
|
+
client.get("/vehicles/#{id}/data_request/#{name}")
|
201
201
|
end
|
202
202
|
|
203
203
|
def command(name, body: nil)
|
204
|
-
|
204
|
+
client.post("/vehicles/#{id}/command/#{name}", body: body)
|
205
205
|
end
|
206
206
|
end
|
207
207
|
end
|
data/lib/tesla_api/version.rb
CHANGED
@@ -19,12 +19,7 @@ RSpec.describe TeslaApi::Client do
|
|
19
19
|
|
20
20
|
it 'logs into the API' do
|
21
21
|
tesla_api.login!(ENV['TESLA_PASS'])
|
22
|
-
expect(a_request(:post, "https://#{URI.parse(
|
23
|
-
end
|
24
|
-
|
25
|
-
it 'sets a Bearer token header' do
|
26
|
-
tesla_api.login!(ENV['TESLA_PASS'])
|
27
|
-
expect(tesla_api.class.headers).to include({'Authorization' => /Bearer [a-z0-9]{32}/})
|
22
|
+
expect(a_request(:post, "https://#{URI.parse(TeslaApi::Client::BASE_URI).host}/oauth/token")).to have_been_made.once
|
28
23
|
end
|
29
24
|
|
30
25
|
it 'obtains a Bearer token' do
|
@@ -63,10 +58,6 @@ RSpec.describe TeslaApi::Client do
|
|
63
58
|
it 'is not expired' do
|
64
59
|
expect(tesla_api.expired?).to eq(false)
|
65
60
|
end
|
66
|
-
|
67
|
-
it 'sets a Bearer token header' do
|
68
|
-
expect(tesla_api.class.headers).to include({'Authorization' => "Bearer #{access_token}"})
|
69
|
-
end
|
70
61
|
end
|
71
62
|
|
72
63
|
describe '#refresh_access_token', vcr: {cassette_name: 'client-refresh'} do
|
data/tesla_api.gemspec
CHANGED
@@ -14,9 +14,9 @@ Gem::Specification.new do |spec|
|
|
14
14
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
15
15
|
spec.require_paths = ['lib']
|
16
16
|
|
17
|
-
spec.add_dependency '
|
17
|
+
spec.add_dependency 'faraday'
|
18
|
+
spec.add_dependency 'faraday_middleware'
|
18
19
|
spec.add_dependency 'faye-websocket'
|
19
|
-
spec.add_dependency 'em-http-request'
|
20
20
|
|
21
21
|
spec.add_development_dependency 'bundler', '~> 2.0'
|
22
22
|
spec.add_development_dependency 'rake', '~> 12.0'
|
metadata
CHANGED
@@ -1,17 +1,17 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tesla_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 3.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Dorr
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-09-
|
11
|
+
date: 2019-09-25 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
|
- - ">="
|
@@ -25,7 +25,7 @@ dependencies:
|
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '0'
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
|
-
name:
|
28
|
+
name: faraday_middleware
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
30
30
|
requirements:
|
31
31
|
- - ">="
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: faye-websocket
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - ">="
|