tesla_api 3.0.7 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/test.yml +36 -0
- data/docs/api-basics/authentication.md +163 -36
- data/docs/vehicle/optioncodes.md +82 -42
- data/docs/vehicle/state/data.md +42 -37
- data/lib/tesla_api/client.rb +76 -11
- data/lib/tesla_api/version.rb +1 -1
- data/spec/cassettes/client-login.yml +254 -46
- data/spec/cassettes/client-refresh.yml +109 -49
- data/spec/lib/tesla_api/client_spec.rb +20 -38
- metadata +6 -8
- data/.travis.yml +0 -16
- data/spec/cassettes/client-login_timeout.yml +0 -83
@@ -1,51 +1,111 @@
|
|
1
1
|
---
|
2
2
|
http_interactions:
|
3
|
-
- request:
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
3
|
+
- request:
|
4
|
+
method: post
|
5
|
+
uri: https://auth.tesla.com/oauth2/v3/token
|
6
|
+
body:
|
7
|
+
encoding: UTF-8
|
8
|
+
string: '{"grant_type":"refresh_token","scope":"openid email offline_access","client_id":"ownerapi","client_secret":"<TESLA_CLIENT_SECRET>","refresh_token":"<TESLA_REFRESH_TOKEN>"}'
|
9
|
+
headers:
|
10
|
+
User-Agent:
|
11
|
+
- github.com/timdorr/tesla-api v:3.0.7
|
12
|
+
Content-Type:
|
13
|
+
- application/json
|
14
|
+
Accept-Encoding:
|
15
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
16
|
+
Accept:
|
17
|
+
- '*/*'
|
18
|
+
response:
|
19
|
+
status:
|
20
|
+
code: 200
|
21
|
+
message: OK
|
22
|
+
headers:
|
23
|
+
Server:
|
24
|
+
- nginx
|
25
|
+
Content-Type:
|
26
|
+
- application/json
|
27
|
+
X-Dns-Prefetch-Control:
|
28
|
+
- 'off'
|
29
|
+
X-Frame-Options:
|
30
|
+
- DENY
|
31
|
+
Strict-Transport-Security:
|
32
|
+
- max-age=15552000; includeSubDomains
|
33
|
+
X-Download-Options:
|
34
|
+
- noopen
|
35
|
+
X-Content-Type-Options:
|
36
|
+
- nosniff
|
37
|
+
X-Xss-Protection:
|
38
|
+
- 1; mode=block
|
39
|
+
X-Request-Id:
|
40
|
+
- c6575e47-91d3-4a07-9985-358de3dbe39e
|
41
|
+
X-Correlation-Id:
|
42
|
+
- c6575e47-91d3-4a07-9985-358de3dbe39e
|
43
|
+
Cache-Control:
|
44
|
+
- no-store
|
45
|
+
Pragma:
|
46
|
+
- no-cache
|
47
|
+
X-Response-Time:
|
48
|
+
- 24.639ms
|
49
|
+
Date:
|
50
|
+
- Sat, 30 Jan 2021 15:18:43 GMT
|
51
|
+
Content-Length:
|
52
|
+
- '2517'
|
53
|
+
Connection:
|
54
|
+
- keep-alive
|
55
|
+
body:
|
56
|
+
encoding: UTF-8
|
57
|
+
string: '{"access_token":"acess","refresh_token":"<TESLA_REFRESH_TOKEN>","id_token":"id","expires_in":300,"token_type":"Bearer"}'
|
58
|
+
recorded_at: Sat, 30 Jan 2021 15:18:43 GMT
|
59
|
+
- request:
|
60
|
+
method: post
|
61
|
+
uri: https://owner-api.teslamotors.com/oauth/token
|
62
|
+
body:
|
63
|
+
encoding: UTF-8
|
64
|
+
string: '{"grant_type":"urn:ietf:params:oauth:grant-type:jwt-bearer","client_id":"<TESLA_CLIENT_ID>","client_secret":"<TESLA_CLIENT_SECRET>"}'
|
65
|
+
headers:
|
66
|
+
User-Agent:
|
67
|
+
- github.com/timdorr/tesla-api v:3.0.7
|
68
|
+
Authorization:
|
69
|
+
- Bearer bear
|
70
|
+
Content-Type:
|
71
|
+
- application/json
|
72
|
+
Accept-Encoding:
|
73
|
+
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
74
|
+
Accept:
|
75
|
+
- '*/*'
|
76
|
+
response:
|
77
|
+
status:
|
78
|
+
code: 200
|
79
|
+
message: OK
|
80
|
+
headers:
|
81
|
+
Date:
|
82
|
+
- Sat, 30 Jan 2021 15:18:44 GMT
|
83
|
+
Content-Type:
|
84
|
+
- application/json; charset=utf-8
|
85
|
+
Transfer-Encoding:
|
86
|
+
- chunked
|
87
|
+
Connection:
|
88
|
+
- keep-alive
|
89
|
+
Vary:
|
90
|
+
- Accept-Encoding
|
91
|
+
X-Frame-Options:
|
92
|
+
- SAMEORIGIN
|
93
|
+
X-Xss-Protection:
|
94
|
+
- 1; mode=block
|
95
|
+
X-Content-Type-Options:
|
96
|
+
- nosniff
|
97
|
+
Etag:
|
98
|
+
- W/"85c5baa66d3db433982e5744ccc1e96e"
|
99
|
+
Cache-Control:
|
100
|
+
- max-age=0, private, must-revalidate
|
101
|
+
X-Request-Id:
|
102
|
+
- 2f0ad7f617da468d211594930c0e88d52f0ad7f617da468d211594930c0e88d5
|
103
|
+
X-Runtime:
|
104
|
+
- '0.301686'
|
105
|
+
Strict-Transport-Security:
|
106
|
+
- max-age=15724800; includeSubDomains
|
107
|
+
body:
|
108
|
+
encoding: ASCII-8BIT
|
109
|
+
string: '{"access_token":"qts-deadbeef","token_type":"bearer","expires_in":3888000,"refresh_token":"yes","created_at":1612019924}'
|
110
|
+
recorded_at: Sat, 30 Jan 2021 15:18:44 GMT
|
111
|
+
recorded_with: VCR 6.0.0
|
@@ -3,6 +3,8 @@ require 'spec_helper'
|
|
3
3
|
RSpec.describe TeslaApi::Client do
|
4
4
|
subject(:tesla_api) { TeslaApi::Client.new(email: ENV['TESLA_EMAIL']) }
|
5
5
|
|
6
|
+
it { is_expected.to be_a(TeslaApi::Client) }
|
7
|
+
|
6
8
|
context 'password grant auth' do
|
7
9
|
describe '#new' do
|
8
10
|
it 'has no expiry date' do
|
@@ -14,9 +16,13 @@ RSpec.describe TeslaApi::Client do
|
|
14
16
|
end
|
15
17
|
end
|
16
18
|
|
17
|
-
describe '#login!', vcr: {
|
18
|
-
|
19
|
-
|
19
|
+
describe '#login!', vcr: {
|
20
|
+
cassette_name: 'client-login',
|
21
|
+
match_requests_on: [
|
22
|
+
:method,
|
23
|
+
VCR.request_matchers.uri_without_params(:code_challenge, :state)
|
24
|
+
]
|
25
|
+
} do
|
20
26
|
it 'logs into the API' do
|
21
27
|
tesla_api.login!(ENV['TESLA_PASS'])
|
22
28
|
expect(a_request(:post, "https://#{URI.parse(TeslaApi::Client::BASE_URI).host}/oauth/token")).to have_been_made.once
|
@@ -24,22 +30,22 @@ RSpec.describe TeslaApi::Client do
|
|
24
30
|
|
25
31
|
it 'obtains a Bearer token' do
|
26
32
|
tesla_api.login!(ENV['TESLA_PASS'])
|
27
|
-
expect(tesla_api.access_token).to
|
33
|
+
expect(tesla_api.access_token).to start_with('qts-')
|
28
34
|
end
|
29
35
|
|
30
36
|
it 'set a expiry date' do
|
31
37
|
tesla_api.login!(ENV['TESLA_PASS'])
|
32
|
-
expect(tesla_api.access_token_expires_at).to eq(Time.at(
|
38
|
+
expect(tesla_api.access_token_expires_at).to eq(Time.at(1612019326 + 3888000).to_datetime)
|
33
39
|
end
|
34
40
|
|
35
41
|
it 'obtains a refresh token' do
|
36
42
|
tesla_api.login!(ENV['TESLA_PASS'])
|
37
|
-
expect(tesla_api.refresh_token).to
|
43
|
+
expect(tesla_api.refresh_token).to start_with('eyJ')
|
38
44
|
end
|
39
45
|
|
40
46
|
it 'expose expiry status' do
|
41
47
|
tesla_api.login!(ENV['TESLA_PASS'])
|
42
|
-
expect(tesla_api.expired?).to eq(
|
48
|
+
expect(tesla_api.expired?).to eq(false)
|
43
49
|
end
|
44
50
|
end
|
45
51
|
end
|
@@ -60,7 +66,13 @@ RSpec.describe TeslaApi::Client do
|
|
60
66
|
end
|
61
67
|
end
|
62
68
|
|
63
|
-
describe '#refresh_access_token', vcr: {
|
69
|
+
describe '#refresh_access_token', vcr: {
|
70
|
+
cassette_name: 'client-refresh',
|
71
|
+
match_requests_on: [
|
72
|
+
:method,
|
73
|
+
VCR.request_matchers.uri_without_params(:code_challenge, :state)
|
74
|
+
]
|
75
|
+
} do
|
64
76
|
it 'refreshes the access token' do
|
65
77
|
tesla_api.refresh_access_token
|
66
78
|
expect(tesla_api.access_token).not_to eq(access_token)
|
@@ -73,34 +85,4 @@ RSpec.describe TeslaApi::Client do
|
|
73
85
|
expect(tesla_api.vehicles).to include(TeslaApi::Vehicle)
|
74
86
|
end
|
75
87
|
end
|
76
|
-
|
77
|
-
describe 'retry options', vcr: { cassette_name: 'client-login_timeout' } do
|
78
|
-
subject(:tesla_api) { TeslaApi::Client.new(
|
79
|
-
access_token: ENV['TESLA_ACCESS_TOKEN'],
|
80
|
-
retry_options: retry_options
|
81
|
-
) }
|
82
|
-
|
83
|
-
let(:retry_options) {{
|
84
|
-
max: 2,
|
85
|
-
methods: [:post],
|
86
|
-
retry_statuses: [408]
|
87
|
-
}}
|
88
|
-
|
89
|
-
context 'with retry' do
|
90
|
-
it 'obtains a Bearer token after retry' do
|
91
|
-
tesla_api.login!(ENV['TESLA_PASS'])
|
92
|
-
expect(tesla_api.access_token).to be
|
93
|
-
end
|
94
|
-
end
|
95
|
-
|
96
|
-
context 'without retry' do
|
97
|
-
let(:retry_options) { nil }
|
98
|
-
|
99
|
-
it 'raises an error' do
|
100
|
-
expect {
|
101
|
-
tesla_api.login!(ENV['TESLA_PASS'])
|
102
|
-
}.to raise_error(Faraday::ClientError)
|
103
|
-
end
|
104
|
-
end
|
105
|
-
end
|
106
88
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tesla_api
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 3.0
|
4
|
+
version: 3.1.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Tim Dorr
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2021-01-30 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: async-websocket
|
@@ -145,10 +145,10 @@ extensions: []
|
|
145
145
|
extra_rdoc_files: []
|
146
146
|
files:
|
147
147
|
- ".gitbook.yml"
|
148
|
+
- ".github/workflows/test.yml"
|
148
149
|
- ".gitignore"
|
149
150
|
- ".rspec"
|
150
151
|
- ".tool-versions"
|
151
|
-
- ".travis.yml"
|
152
152
|
- Gemfile
|
153
153
|
- LICENSE
|
154
154
|
- README.md
|
@@ -198,7 +198,6 @@ files:
|
|
198
198
|
- lib/tesla_api/vehicle.rb
|
199
199
|
- lib/tesla_api/version.rb
|
200
200
|
- spec/cassettes/client-login.yml
|
201
|
-
- spec/cassettes/client-login_timeout.yml
|
202
201
|
- spec/cassettes/client-refresh.yml
|
203
202
|
- spec/cassettes/client-vehicles.yml
|
204
203
|
- spec/cassettes/vehicle-activate_speed_limit.yml
|
@@ -265,7 +264,7 @@ homepage: https://github.com/timdorr/tesla-api
|
|
265
264
|
licenses:
|
266
265
|
- MIT
|
267
266
|
metadata: {}
|
268
|
-
post_install_message:
|
267
|
+
post_install_message:
|
269
268
|
rdoc_options: []
|
270
269
|
require_paths:
|
271
270
|
- lib
|
@@ -281,12 +280,11 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
281
280
|
version: '0'
|
282
281
|
requirements: []
|
283
282
|
rubygems_version: 3.1.4
|
284
|
-
signing_key:
|
283
|
+
signing_key:
|
285
284
|
specification_version: 4
|
286
285
|
summary: A wrapper for the Tesla JSON API
|
287
286
|
test_files:
|
288
287
|
- spec/cassettes/client-login.yml
|
289
|
-
- spec/cassettes/client-login_timeout.yml
|
290
288
|
- spec/cassettes/client-refresh.yml
|
291
289
|
- spec/cassettes/client-vehicles.yml
|
292
290
|
- spec/cassettes/vehicle-activate_speed_limit.yml
|
data/.travis.yml
DELETED
@@ -1,16 +0,0 @@
|
|
1
|
-
language: ruby
|
2
|
-
rvm:
|
3
|
-
- 2.7
|
4
|
-
env:
|
5
|
-
global:
|
6
|
-
- TESLA_EMAIL=elon.musk@teslamotors.com
|
7
|
-
- TESLA_PASS=oilLOL
|
8
|
-
- TESLA_CLIENT_ID=1
|
9
|
-
- TESLA_CLIENT_SECRET=2
|
10
|
-
- TESLA_ACCESS_TOKEN=3
|
11
|
-
- TESLA_REFRESH_TOKEN=4
|
12
|
-
before_install:
|
13
|
-
- gem update --system
|
14
|
-
- gem install bundler
|
15
|
-
notifications:
|
16
|
-
email: false
|
@@ -1,83 +0,0 @@
|
|
1
|
-
---
|
2
|
-
http_interactions:
|
3
|
-
- request:
|
4
|
-
method: post
|
5
|
-
uri: https://owner-api.teslamotors.com/oauth/token
|
6
|
-
body:
|
7
|
-
encoding: UTF-8
|
8
|
-
string: grant_type=password&client_id=<TESLA_CLIENT_ID>&client_secret=<TESLA_CLIENT_SECRET>&email=<TESLA_EMAIL>&password=<TESLA_PASS>
|
9
|
-
headers:
|
10
|
-
Accept-Encoding:
|
11
|
-
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
12
|
-
Accept:
|
13
|
-
- "*/*"
|
14
|
-
User-Agent:
|
15
|
-
- Ruby
|
16
|
-
response:
|
17
|
-
status:
|
18
|
-
code: 408
|
19
|
-
message: Request Timeout
|
20
|
-
headers:
|
21
|
-
Server:
|
22
|
-
- nginx
|
23
|
-
Date:
|
24
|
-
- Mon, 15 Dec 2014 03:09:22 GMT
|
25
|
-
Content-Type:
|
26
|
-
- application/json; charset=utf-8
|
27
|
-
Transfer-Encoding:
|
28
|
-
- chunked
|
29
|
-
Connection:
|
30
|
-
- keep-alive
|
31
|
-
Status:
|
32
|
-
- 408 Request Timeout
|
33
|
-
body:
|
34
|
-
encoding: UTF-8
|
35
|
-
string: '{}'
|
36
|
-
http_version:
|
37
|
-
recorded_at: Mon, 15 Dec 2014 03:09:22 GMT
|
38
|
-
- request:
|
39
|
-
method: post
|
40
|
-
uri: https://owner-api.teslamotors.com/oauth/token
|
41
|
-
body:
|
42
|
-
encoding: UTF-8
|
43
|
-
string: grant_type=password&client_id=<TESLA_CLIENT_ID>&client_secret=<TESLA_CLIENT_SECRET>&email=<TESLA_EMAIL>&password=<TESLA_PASS>
|
44
|
-
headers:
|
45
|
-
Accept-Encoding:
|
46
|
-
- gzip;q=1.0,deflate;q=0.6,identity;q=0.3
|
47
|
-
Accept:
|
48
|
-
- "*/*"
|
49
|
-
User-Agent:
|
50
|
-
- Ruby
|
51
|
-
response:
|
52
|
-
status:
|
53
|
-
code: 200
|
54
|
-
message: OK
|
55
|
-
headers:
|
56
|
-
Server:
|
57
|
-
- nginx
|
58
|
-
Date:
|
59
|
-
- Mon, 15 Dec 2014 03:09:22 GMT
|
60
|
-
Content-Type:
|
61
|
-
- application/json; charset=utf-8
|
62
|
-
Transfer-Encoding:
|
63
|
-
- chunked
|
64
|
-
Connection:
|
65
|
-
- keep-alive
|
66
|
-
Status:
|
67
|
-
- 200 OK
|
68
|
-
Cache-Control:
|
69
|
-
- no-store
|
70
|
-
Pragma:
|
71
|
-
- no-cache
|
72
|
-
X-Ua-Compatible:
|
73
|
-
- IE=Edge,chrome=1
|
74
|
-
X-Request-Id:
|
75
|
-
- 349d563d345a9694c610770b743d3006
|
76
|
-
X-Runtime:
|
77
|
-
- '0.416152'
|
78
|
-
body:
|
79
|
-
encoding: UTF-8
|
80
|
-
string: '{"access_token":"1cba4845a8653d4b731440e9911d84304a179bd16a9ecbc9b649f2d8e0f6947e","token_type":"bearer","expires_in":7776000,"refresh_token":"fea03b395fa4e72ebc399d9cda6163dcf438c248f744ebdd5bfcda571f5f317f","created_at":1475777133}'
|
81
|
-
http_version:
|
82
|
-
recorded_at: Mon, 15 Dec 2014 03:09:22 GMT
|
83
|
-
recorded_with: VCR 2.9.3
|