tesla-fleet-api 0.8.3__tar.gz → 0.8.5__tar.gz
Sign up to get free protection for your applications and to get access to all the features.
- {tesla_fleet_api-0.8.3/tesla_fleet_api.egg-info → tesla_fleet_api-0.8.5}/PKG-INFO +4 -1
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/setup.py +2 -2
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/const.py +2 -1
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/exceptions.py +216 -21
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/teslafleetapi.py +3 -1
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/teslafleetoauth.py +1 -1
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/vehiclesigned.py +27 -32
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5/tesla_fleet_api.egg-info}/PKG-INFO +4 -1
- tesla_fleet_api-0.8.5/tesla_fleet_api.egg-info/requires.txt +5 -0
- tesla_fleet_api-0.8.3/tesla_fleet_api.egg-info/requires.txt +0 -2
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/LICENSE +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/README.md +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/setup.cfg +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/__init__.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/charging.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/energy.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/energyspecific.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/partner.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/__init__.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/__init__.pyi +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/car_server_pb2.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/common_pb2.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/errors_pb2.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/keys_pb2.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/signatures_pb2.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/universal_message_pb2.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/vcsec_pb2.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/vehicle_pb2.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/ratecalculator.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/teslafleetopensource.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/teslemetry.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/tessie.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/user.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/vehicle.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/vehiclespecific.py +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api.egg-info/SOURCES.txt +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api.egg-info/dependency_links.txt +0 -0
- {tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tesla_fleet_api
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.5
|
4
4
|
Summary: Tesla Fleet API library for Python
|
5
5
|
Home-page: https://github.com/Teslemetry/tesla_fleet_api
|
6
6
|
Author: Brett Adams
|
@@ -13,7 +13,10 @@ Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
14
14
|
License-File: LICENSE
|
15
15
|
Requires-Dist: aiohttp
|
16
|
+
Requires-Dist: aiofiles
|
16
17
|
Requires-Dist: aiolimiter
|
18
|
+
Requires-Dist: cryptography
|
19
|
+
Requires-Dist: protobuf
|
17
20
|
|
18
21
|
# Tesla Fleet Api
|
19
22
|
Python library for Tesla Fleet API and Teslemetry.
|
@@ -5,7 +5,7 @@ with open("README.md", "r") as fh:
|
|
5
5
|
|
6
6
|
setuptools.setup(
|
7
7
|
name="tesla_fleet_api",
|
8
|
-
version="0.8.
|
8
|
+
version="0.8.5",
|
9
9
|
author="Brett Adams",
|
10
10
|
author_email="hello@teslemetry.com",
|
11
11
|
description="Tesla Fleet API library for Python",
|
@@ -20,5 +20,5 @@ setuptools.setup(
|
|
20
20
|
"Operating System :: OS Independent",
|
21
21
|
],
|
22
22
|
python_requires=">=3.10",
|
23
|
-
install_requires=["aiohttp", "aiolimiter"],
|
23
|
+
install_requires=["aiohttp", "aiofiles", "aiolimiter", "cryptography", "protobuf"],
|
24
24
|
)
|
@@ -3,7 +3,7 @@
|
|
3
3
|
from enum import Enum
|
4
4
|
import logging
|
5
5
|
|
6
|
-
VERSION = "0.8.
|
6
|
+
VERSION = "0.8.5"
|
7
7
|
LOGGER = logging.getLogger(__package__)
|
8
8
|
SERVERS = {
|
9
9
|
"na": "https://fleet-api.prd.na.vn.cloud.tesla.com",
|
@@ -125,6 +125,7 @@ class Scope(StrEnum):
|
|
125
125
|
OFFLINE_ACCESS = "offline_access"
|
126
126
|
USER_DATA = "user_data"
|
127
127
|
VEHICLE_DEVICE_DATA = "vehicle_device_data"
|
128
|
+
VEHICLE_LOCATION = "vehicle_location"
|
128
129
|
VEHICLE_CMDS = "vehicle_cmds"
|
129
130
|
VEHICLE_CHARGING_CMDS = "vehicle_charging_cmds"
|
130
131
|
ENERGY_DEVICE_DATA = "energy_device_data"
|
@@ -293,146 +293,146 @@ class LibraryError(Exception):
|
|
293
293
|
"""Errors related to this library."""
|
294
294
|
|
295
295
|
|
296
|
-
class
|
296
|
+
class TeslaFleetInformationFault(TeslaFleetError):
|
297
297
|
"""Vehicle has responded with an error when sending a signed command"""
|
298
298
|
|
299
299
|
message = "Vehicle has responded with an error when sending a signed command"
|
300
300
|
|
301
301
|
|
302
|
-
class UnknownFault(
|
302
|
+
class UnknownFault(TeslaFleetInformationFault):
|
303
303
|
"""Unknown fault on signed command."""
|
304
304
|
|
305
305
|
message = "Unknown fault on signed command."
|
306
306
|
code = 1
|
307
307
|
|
308
308
|
|
309
|
-
class NotOnWhitelistFault(
|
309
|
+
class NotOnWhitelistFault(TeslaFleetInformationFault):
|
310
310
|
"""Not on whitelist fault on signed command."""
|
311
311
|
|
312
312
|
message = "Not on whitelist fault on signed command."
|
313
313
|
code = 2
|
314
314
|
|
315
315
|
|
316
|
-
class IVSmallerThanExpectedFault(
|
316
|
+
class IVSmallerThanExpectedFault(TeslaFleetInformationFault):
|
317
317
|
"""IV smaller than expected fault on signed command."""
|
318
318
|
|
319
319
|
message = "IV smaller than expected fault on signed command."
|
320
320
|
code = 3
|
321
321
|
|
322
322
|
|
323
|
-
class InvalidTokenFault(
|
323
|
+
class InvalidTokenFault(TeslaFleetInformationFault):
|
324
324
|
"""Invalid token fault on signed command."""
|
325
325
|
|
326
326
|
message = "Invalid token fault on signed command."
|
327
327
|
code = 4
|
328
328
|
|
329
329
|
|
330
|
-
class TokenAndCounterInvalidFault(
|
330
|
+
class TokenAndCounterInvalidFault(TeslaFleetInformationFault):
|
331
331
|
"""Token and counter invalid fault on signed command."""
|
332
332
|
|
333
333
|
message = "Token and counter invalid fault on signed command."
|
334
334
|
code = 5
|
335
335
|
|
336
336
|
|
337
|
-
class AESDecryptAuthFault(
|
337
|
+
class AESDecryptAuthFault(TeslaFleetInformationFault):
|
338
338
|
"""AES decrypt auth fault on signed command."""
|
339
339
|
|
340
340
|
message = "AES decrypt auth fault on signed command."
|
341
341
|
code = 6
|
342
342
|
|
343
343
|
|
344
|
-
class ECDSAInputFault(
|
344
|
+
class ECDSAInputFault(TeslaFleetInformationFault):
|
345
345
|
"""ECDSA input fault on signed command."""
|
346
346
|
|
347
347
|
message = "ECDSA input fault on signed command."
|
348
348
|
code = 7
|
349
349
|
|
350
350
|
|
351
|
-
class ECDSASignatureFault(
|
351
|
+
class ECDSASignatureFault(TeslaFleetInformationFault):
|
352
352
|
"""ECDSA signature fault on signed command."""
|
353
353
|
|
354
354
|
message = "ECDSA signature fault on signed command."
|
355
355
|
code = 8
|
356
356
|
|
357
357
|
|
358
|
-
class LocalEntityStartFault(
|
358
|
+
class LocalEntityStartFault(TeslaFleetInformationFault):
|
359
359
|
"""Local entity start fault on signed command."""
|
360
360
|
|
361
361
|
message = "Local entity start fault on signed command."
|
362
362
|
code = 9
|
363
363
|
|
364
364
|
|
365
|
-
class LocalEntityResultFault(
|
365
|
+
class LocalEntityResultFault(TeslaFleetInformationFault):
|
366
366
|
"""Local entity result fault on signed command."""
|
367
367
|
|
368
368
|
message = "Local entity result fault on signed command."
|
369
369
|
code = 10
|
370
370
|
|
371
371
|
|
372
|
-
class CouldNotRetrieveKeyFault(
|
372
|
+
class CouldNotRetrieveKeyFault(TeslaFleetInformationFault):
|
373
373
|
"""Could not retrieve key fault on signed command."""
|
374
374
|
|
375
375
|
message = "Could not retrieve key fault on signed command."
|
376
376
|
code = 11
|
377
377
|
|
378
378
|
|
379
|
-
class CouldNotRetrieveTokenFault(
|
379
|
+
class CouldNotRetrieveTokenFault(TeslaFleetInformationFault):
|
380
380
|
"""Could not retrieve token fault on signed command."""
|
381
381
|
|
382
382
|
message = "Could not retrieve token fault on signed command."
|
383
383
|
code = 12
|
384
384
|
|
385
385
|
|
386
|
-
class SignatureTooShortFault(
|
386
|
+
class SignatureTooShortFault(TeslaFleetInformationFault):
|
387
387
|
"""Signature too short fault on signed command."""
|
388
388
|
|
389
389
|
message = "Signature too short fault on signed command."
|
390
390
|
code = 13
|
391
391
|
|
392
392
|
|
393
|
-
class TokenIsIncorrectLengthFault(
|
393
|
+
class TokenIsIncorrectLengthFault(TeslaFleetInformationFault):
|
394
394
|
"""Token is incorrect length fault on signed command."""
|
395
395
|
|
396
396
|
message = "Token is incorrect length fault on signed command."
|
397
397
|
code = 14
|
398
398
|
|
399
399
|
|
400
|
-
class IncorrectEpochFault(
|
400
|
+
class IncorrectEpochFault(TeslaFleetInformationFault):
|
401
401
|
"""Incorrect epoch fault on signed command."""
|
402
402
|
|
403
403
|
message = "Incorrect epoch fault on signed command."
|
404
404
|
code = 15
|
405
405
|
|
406
406
|
|
407
|
-
class IVIncorrectLengthFault(
|
407
|
+
class IVIncorrectLengthFault(TeslaFleetInformationFault):
|
408
408
|
"""IV incorrect length fault on signed command."""
|
409
409
|
|
410
410
|
message = "IV incorrect length fault on signed command."
|
411
411
|
code = 16
|
412
412
|
|
413
413
|
|
414
|
-
class TimeExpiredFault(
|
414
|
+
class TimeExpiredFault(TeslaFleetInformationFault):
|
415
415
|
"""Time expired fault on signed command."""
|
416
416
|
|
417
417
|
message = "Time expired fault on signed command."
|
418
418
|
code = 17
|
419
419
|
|
420
420
|
|
421
|
-
class NotProvisionedWithIdentityFault(
|
421
|
+
class NotProvisionedWithIdentityFault(TeslaFleetInformationFault):
|
422
422
|
"""Not provisioned with identity fault on signed command."""
|
423
423
|
|
424
424
|
message = "Not provisioned with identity fault on signed command."
|
425
425
|
code = 18
|
426
426
|
|
427
427
|
|
428
|
-
class CouldNotHashMetadataFault(
|
428
|
+
class CouldNotHashMetadataFault(TeslaFleetInformationFault):
|
429
429
|
"""Could not hash metadata fault on signed command."""
|
430
430
|
|
431
431
|
message = "Could not hash metadata fault on signed command."
|
432
432
|
code = 19
|
433
433
|
|
434
434
|
|
435
|
-
|
435
|
+
INFORMATION_FAULTS = [
|
436
436
|
None,
|
437
437
|
UnknownFault,
|
438
438
|
NotOnWhitelistFault,
|
@@ -456,6 +456,201 @@ SIGNING_EXCEPTIONS = [
|
|
456
456
|
]
|
457
457
|
|
458
458
|
|
459
|
+
class TeslaFleetMessageFault(TeslaFleetError):
|
460
|
+
"""Vehicle has responded with an error when sending a signed command"""
|
461
|
+
|
462
|
+
message = "Vehicle has responded with an error when sending a signed command"
|
463
|
+
|
464
|
+
|
465
|
+
class TeslaFleetMessageFaultBusy(TeslaFleetMessageFault):
|
466
|
+
"""Vehicle is busy"""
|
467
|
+
|
468
|
+
message = "Vehicle is busy"
|
469
|
+
code = 1
|
470
|
+
|
471
|
+
|
472
|
+
class TeslaFleetMessageFaultTimeout(TeslaFleetMessageFault):
|
473
|
+
"""Vehicle timed out"""
|
474
|
+
|
475
|
+
message = "Vehicle timed out"
|
476
|
+
code = 2
|
477
|
+
|
478
|
+
|
479
|
+
class TeslaFleetMessageFaultUnknownKeyId(TeslaFleetMessageFault):
|
480
|
+
"""Unknown Key ID"""
|
481
|
+
|
482
|
+
message = "Unknown Key ID"
|
483
|
+
code = 3
|
484
|
+
|
485
|
+
|
486
|
+
class TeslaFleetMessageFaultInactiveKey(TeslaFleetMessageFault):
|
487
|
+
"""Inactive Key"""
|
488
|
+
|
489
|
+
message = "Inactive Key"
|
490
|
+
code = 4
|
491
|
+
|
492
|
+
|
493
|
+
class TeslaFleetMessageFaultInvalidSignature(TeslaFleetMessageFault):
|
494
|
+
"""Invalid Signature"""
|
495
|
+
|
496
|
+
message = "Invalid Signature"
|
497
|
+
code = 5
|
498
|
+
|
499
|
+
|
500
|
+
class TeslaFleetMessageFaultInvalidTokenOrCounter(TeslaFleetMessageFault):
|
501
|
+
"""Invalid Token or Counter"""
|
502
|
+
|
503
|
+
message = "Invalid Token or Counter"
|
504
|
+
code = 6
|
505
|
+
|
506
|
+
|
507
|
+
class TeslaFleetMessageFaultInsufficientPrivileges(TeslaFleetMessageFault):
|
508
|
+
"""Insufficient Privileges"""
|
509
|
+
|
510
|
+
message = "Insufficient Privileges"
|
511
|
+
code = 7
|
512
|
+
|
513
|
+
|
514
|
+
class TeslaFleetMessageFaultInvalidDomains(TeslaFleetMessageFault):
|
515
|
+
"""Invalid Domains"""
|
516
|
+
|
517
|
+
message = "Invalid Domains"
|
518
|
+
code = 8
|
519
|
+
|
520
|
+
|
521
|
+
class TeslaFleetMessageFaultInvalidCommand(TeslaFleetMessageFault):
|
522
|
+
"""Invalid Command"""
|
523
|
+
|
524
|
+
message = "Invalid Command"
|
525
|
+
code = 9
|
526
|
+
|
527
|
+
|
528
|
+
class TeslaFleetMessageFaultDecoding(TeslaFleetMessageFault):
|
529
|
+
"""Decoding Error"""
|
530
|
+
|
531
|
+
message = "Decoding Error"
|
532
|
+
code = 10
|
533
|
+
|
534
|
+
|
535
|
+
class TeslaFleetMessageFaultInternal(TeslaFleetMessageFault):
|
536
|
+
"""Internal Error"""
|
537
|
+
|
538
|
+
message = "Internal Error"
|
539
|
+
code = 11
|
540
|
+
|
541
|
+
|
542
|
+
class TeslaFleetMessageFaultWrongPersonalization(TeslaFleetMessageFault):
|
543
|
+
"""Wrong Personalization"""
|
544
|
+
|
545
|
+
message = "Wrong Personalization"
|
546
|
+
code = 12
|
547
|
+
|
548
|
+
|
549
|
+
class TeslaFleetMessageFaultBadParameter(TeslaFleetMessageFault):
|
550
|
+
"""Bad Parameter"""
|
551
|
+
|
552
|
+
message = "Bad Parameter"
|
553
|
+
code = 13
|
554
|
+
|
555
|
+
|
556
|
+
class TeslaFleetMessageFaultKeychainIsFull(TeslaFleetMessageFault):
|
557
|
+
"""Keychain is Full"""
|
558
|
+
|
559
|
+
message = "Keychain is Full"
|
560
|
+
code = 14
|
561
|
+
|
562
|
+
|
563
|
+
class TeslaFleetMessageFaultIncorrectEpoch(TeslaFleetMessageFault):
|
564
|
+
"""Incorrect Epoch"""
|
565
|
+
|
566
|
+
message = "Incorrect Epoch"
|
567
|
+
code = 15
|
568
|
+
|
569
|
+
|
570
|
+
class TeslaFleetMessageFaultIVIncorrectLength(TeslaFleetMessageFault):
|
571
|
+
"""IV Incorrect Length"""
|
572
|
+
|
573
|
+
message = "IV Incorrect Length"
|
574
|
+
code = 16
|
575
|
+
|
576
|
+
|
577
|
+
class TeslaFleetMessageFaultTimeExpired(TeslaFleetMessageFault):
|
578
|
+
"""Time Expired"""
|
579
|
+
|
580
|
+
message = "Time Expired"
|
581
|
+
code = 17
|
582
|
+
|
583
|
+
|
584
|
+
class TeslaFleetMessageFaultNotProvisionedWithIdentity(TeslaFleetMessageFault):
|
585
|
+
"""Not Provisioned with Identity"""
|
586
|
+
|
587
|
+
message = "Not Provisioned with Identity"
|
588
|
+
code = 18
|
589
|
+
|
590
|
+
|
591
|
+
class TeslaFleetMessageFaultCouldNotHashMetadata(TeslaFleetMessageFault):
|
592
|
+
"""Could not Hash Metadata"""
|
593
|
+
|
594
|
+
message = "Could not Hash Metadata"
|
595
|
+
code = 19
|
596
|
+
|
597
|
+
|
598
|
+
class TeslaFleetMessageFaultTimeToLiveTooLong(TeslaFleetMessageFault):
|
599
|
+
"""Time to Live Too Long"""
|
600
|
+
|
601
|
+
message = "Time to Live Too Long"
|
602
|
+
code = 20
|
603
|
+
|
604
|
+
|
605
|
+
class TeslaFleetMessageFaultRemoteAccessDisabled(TeslaFleetMessageFault):
|
606
|
+
"""Remote Access Disabled"""
|
607
|
+
|
608
|
+
message = "Remote Access Disabled"
|
609
|
+
code = 21
|
610
|
+
|
611
|
+
|
612
|
+
class TeslaFleetMessageFaultRemoteServiceAccessDisabled(TeslaFleetMessageFault):
|
613
|
+
"""Remote Service Access Disabled"""
|
614
|
+
|
615
|
+
message = "Remote Service Access Disabled"
|
616
|
+
code = 22
|
617
|
+
|
618
|
+
|
619
|
+
class TeslaFleetMessageFaultCommandRequiresAccountCredentials(TeslaFleetMessageFault):
|
620
|
+
"""Command Requires Account Credentials"""
|
621
|
+
|
622
|
+
message = "Command Requires Account Credentials"
|
623
|
+
code = 23
|
624
|
+
|
625
|
+
|
626
|
+
MESSAGE_FAULTS = [
|
627
|
+
None,
|
628
|
+
TeslaFleetMessageFaultBusy,
|
629
|
+
TeslaFleetMessageFaultTimeout,
|
630
|
+
TeslaFleetMessageFaultUnknownKeyId,
|
631
|
+
TeslaFleetMessageFaultInactiveKey,
|
632
|
+
TeslaFleetMessageFaultInvalidSignature,
|
633
|
+
TeslaFleetMessageFaultInvalidTokenOrCounter,
|
634
|
+
TeslaFleetMessageFaultInsufficientPrivileges,
|
635
|
+
TeslaFleetMessageFaultInvalidDomains,
|
636
|
+
TeslaFleetMessageFaultInvalidCommand,
|
637
|
+
TeslaFleetMessageFaultDecoding,
|
638
|
+
TeslaFleetMessageFaultInternal,
|
639
|
+
TeslaFleetMessageFaultWrongPersonalization,
|
640
|
+
TeslaFleetMessageFaultBadParameter,
|
641
|
+
TeslaFleetMessageFaultKeychainIsFull,
|
642
|
+
TeslaFleetMessageFaultIncorrectEpoch,
|
643
|
+
TeslaFleetMessageFaultIVIncorrectLength,
|
644
|
+
TeslaFleetMessageFaultTimeExpired,
|
645
|
+
TeslaFleetMessageFaultNotProvisionedWithIdentity,
|
646
|
+
TeslaFleetMessageFaultCouldNotHashMetadata,
|
647
|
+
TeslaFleetMessageFaultTimeToLiveTooLong,
|
648
|
+
TeslaFleetMessageFaultRemoteAccessDisabled,
|
649
|
+
TeslaFleetMessageFaultRemoteServiceAccessDisabled,
|
650
|
+
TeslaFleetMessageFaultCommandRequiresAccountCredentials,
|
651
|
+
]
|
652
|
+
|
653
|
+
|
459
654
|
async def raise_for_status(resp: aiohttp.ClientResponse) -> None:
|
460
655
|
"""Raise an exception if the response status code is >=400."""
|
461
656
|
# https://developer.tesla.com/docs/fleet-api#response-codes
|
@@ -161,7 +161,9 @@ class TeslaFleetApi:
|
|
161
161
|
"api/1/products",
|
162
162
|
)
|
163
163
|
|
164
|
-
async def get_private_key(
|
164
|
+
async def get_private_key(
|
165
|
+
self, path: str = "private_key.pem"
|
166
|
+
) -> ec.EllipticCurvePrivateKey:
|
165
167
|
"""Get or create the private key."""
|
166
168
|
if not exists(path):
|
167
169
|
self.private_key = ec.generate_private_key(
|
@@ -45,7 +45,7 @@ class TeslaFleetOAuth(TeslaFleetApi):
|
|
45
45
|
"""Get the login URL."""
|
46
46
|
if self.redirect_uri is None:
|
47
47
|
raise ValueError("Redirect URI is missing")
|
48
|
-
return f"https://auth.tesla.com/oauth2/v3/authorize?response_type=code&prompt=login&client_id={self.client_id}&redirect_uri={self.redirect_uri}&scope={'
|
48
|
+
return f"https://auth.tesla.com/oauth2/v3/authorize?response_type=code&prompt=login&client_id={self.client_id}&redirect_uri={self.redirect_uri}&scope={'+'.join(scopes)}&state={state}"
|
49
49
|
|
50
50
|
async def get_refresh_token(self, code: str) -> None:
|
51
51
|
"""Get the refresh token."""
|
@@ -9,7 +9,7 @@ import hashlib
|
|
9
9
|
from cryptography.hazmat.primitives.asymmetric import ec
|
10
10
|
from cryptography.hazmat.primitives.serialization import PublicFormat, Encoding
|
11
11
|
|
12
|
-
from
|
12
|
+
from .exceptions import MESSAGE_FAULTS
|
13
13
|
|
14
14
|
from .const import (
|
15
15
|
LOGGER,
|
@@ -22,16 +22,17 @@ from .const import (
|
|
22
22
|
from .vehiclespecific import VehicleSpecific
|
23
23
|
|
24
24
|
from .pb2.universal_message_pb2 import (
|
25
|
-
OPERATIONSTATUS_OK,
|
25
|
+
# OPERATIONSTATUS_OK,
|
26
26
|
OPERATIONSTATUS_WAIT,
|
27
27
|
OPERATIONSTATUS_ERROR,
|
28
28
|
DOMAIN_VEHICLE_SECURITY,
|
29
29
|
DOMAIN_INFOTAINMENT,
|
30
|
+
Domain,
|
31
|
+
# MessageFault_E,
|
30
32
|
RoutableMessage,
|
31
33
|
)
|
32
34
|
from .pb2.car_server_pb2 import (
|
33
35
|
Action,
|
34
|
-
HvacAutoAction,
|
35
36
|
MediaPlayAction,
|
36
37
|
VehicleAction,
|
37
38
|
VehicleControlFlashLightsAction,
|
@@ -48,8 +49,8 @@ from .pb2.car_server_pb2 import (
|
|
48
49
|
HvacSteeringWheelHeaterAction,
|
49
50
|
HvacTemperatureAdjustmentAction,
|
50
51
|
GetNearbyChargingSites,
|
51
|
-
NearbyChargingSites,
|
52
|
-
Superchargers,
|
52
|
+
# NearbyChargingSites,
|
53
|
+
# Superchargers,
|
53
54
|
VehicleControlCancelSoftwareUpdateAction,
|
54
55
|
VehicleControlHonkHornAction,
|
55
56
|
VehicleControlResetValetPinAction,
|
@@ -61,15 +62,13 @@ from .pb2.car_server_pb2 import (
|
|
61
62
|
VehicleControlWindowAction,
|
62
63
|
HvacBioweaponModeAction,
|
63
64
|
AutoSeatClimateAction,
|
64
|
-
Ping,
|
65
|
+
# Ping,
|
65
66
|
ScheduledChargingAction,
|
66
67
|
ScheduledDepartureAction,
|
67
68
|
HvacClimateKeeperAction,
|
68
69
|
SetChargingAmpsAction,
|
69
70
|
SetCabinOverheatProtectionAction,
|
70
71
|
SetVehicleNameAction,
|
71
|
-
ChargePortDoorOpen,
|
72
|
-
ChargePortDoorClose,
|
73
72
|
SetCopTempAction,
|
74
73
|
VehicleControlSetPinToDriveAction,
|
75
74
|
VehicleControlResetPinToDriveAction,
|
@@ -79,8 +78,9 @@ from .pb2.car_server_pb2 import (
|
|
79
78
|
MediaPreviousTrack,
|
80
79
|
MediaPreviousFavorite,
|
81
80
|
)
|
82
|
-
from .pb2.vehicle_pb2 import VehicleState
|
81
|
+
from .pb2.vehicle_pb2 import VehicleState
|
83
82
|
from .pb2.vcsec_pb2 import (
|
83
|
+
# SignedMessage_information_E,
|
84
84
|
UnsignedMessage,
|
85
85
|
RKEAction_E,
|
86
86
|
ClosureMoveRequest,
|
@@ -179,13 +179,19 @@ class VehicleSigned(VehicleSpecific):
|
|
179
179
|
async def _signed_message(self, msg: RoutableMessage) -> RoutableMessage:
|
180
180
|
"""Serialize a message and send to the signed command endpoint."""
|
181
181
|
routable_message = base64.b64encode(msg.SerializeToString()).decode()
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
182
|
+
resp_json = await self.signed_command(routable_message)
|
183
|
+
resp = RoutableMessage()
|
184
|
+
resp.ParseFromString(base64.b64decode(resp_json["response"]))
|
185
|
+
|
186
|
+
LOGGER.error(resp.signedMessageStatus)
|
187
|
+
if resp.signedMessageStatus.operation_status == OPERATIONSTATUS_ERROR:
|
188
|
+
raise MESSAGE_FAULTS[resp.signedMessageStatus.signed_message_fault]
|
189
|
+
|
190
|
+
return resp
|
186
191
|
|
187
192
|
async def _handshake(self, domain: int) -> None:
|
188
193
|
"""Perform a handshake with the vehicle."""
|
194
|
+
LOGGER.debug(f"Handshake with domain {Domain.Name(domain)}")
|
189
195
|
msg = RoutableMessage()
|
190
196
|
msg.to_destination.domain = domain
|
191
197
|
msg.from_destination.routing_address = self._from_destination
|
@@ -197,6 +203,7 @@ class VehicleSigned(VehicleSpecific):
|
|
197
203
|
|
198
204
|
# Get session info with publicKey, epoch, and clock_time
|
199
205
|
info = SessionInfo.FromString(resp.session_info)
|
206
|
+
|
200
207
|
vehicle_public_key = info.publicKey
|
201
208
|
|
202
209
|
# Derive shared key from private key _key and vehicle public key
|
@@ -228,6 +235,7 @@ class VehicleSigned(VehicleSpecific):
|
|
228
235
|
|
229
236
|
async def _send(self, domain: int, command: bytes) -> dict[str, Any]:
|
230
237
|
"""Send a signed message to the vehicle."""
|
238
|
+
LOGGER.debug(f"Sending to domain {Domain.Name(domain)}")
|
231
239
|
msg = RoutableMessage()
|
232
240
|
msg.to_destination.domain = domain
|
233
241
|
msg.from_destination.routing_address = self._from_destination
|
@@ -267,28 +275,15 @@ class VehicleSigned(VehicleSpecific):
|
|
267
275
|
|
268
276
|
resp = await self._signed_message(msg)
|
269
277
|
|
270
|
-
LOGGER.debug(resp)
|
271
|
-
if resp.signedMessageStatus.operation_status == OPERATIONSTATUS_ERROR:
|
272
|
-
raise SIGNING_EXCEPTIONS[resp.signedMessageStatus.signed_message_fault]
|
273
278
|
if resp.signedMessageStatus.operation_status == OPERATIONSTATUS_WAIT:
|
274
279
|
return {"response": {"result": False}}
|
275
280
|
|
276
|
-
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
|
281
|
-
|
282
|
-
# resp_msg = Action()
|
283
|
-
# resp_msg.ParseFromString(resp.protobuf_message_as_bytes)
|
284
|
-
# print("INFOTAINMENT RESPONSE", resp_msg)
|
285
|
-
# #return {"response": {"result": False, "reason": resp_msg}}
|
286
|
-
# elif domain == DOMAIN_VEHICLE_SECURITY:
|
287
|
-
# resp_msg = UnsignedMessage()
|
288
|
-
# resp_msg.ParseFromString(resp.protobuf_message_as_bytes)
|
289
|
-
# print("VCSEC RESPONSE", resp_msg)
|
290
|
-
# print(resp.protobuf_message_as_bytes.encode())
|
291
|
-
# #return {"response": {"result": False, "reason": resp_msg}}
|
281
|
+
LOGGER.debug(resp)
|
282
|
+
reason = resp.protobuf_message_as_bytes[8:].decode()
|
283
|
+
|
284
|
+
if reason:
|
285
|
+
LOGGER.error(reason)
|
286
|
+
return {"response": {"result": False, "reason": reason}}
|
292
287
|
|
293
288
|
return {"response": {"result": True, "reason": ""}}
|
294
289
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: tesla_fleet_api
|
3
|
-
Version: 0.8.
|
3
|
+
Version: 0.8.5
|
4
4
|
Summary: Tesla Fleet API library for Python
|
5
5
|
Home-page: https://github.com/Teslemetry/tesla_fleet_api
|
6
6
|
Author: Brett Adams
|
@@ -13,7 +13,10 @@ Requires-Python: >=3.10
|
|
13
13
|
Description-Content-Type: text/markdown
|
14
14
|
License-File: LICENSE
|
15
15
|
Requires-Dist: aiohttp
|
16
|
+
Requires-Dist: aiofiles
|
16
17
|
Requires-Dist: aiolimiter
|
18
|
+
Requires-Dist: cryptography
|
19
|
+
Requires-Dist: protobuf
|
17
20
|
|
18
21
|
# Tesla Fleet Api
|
19
22
|
Python library for Tesla Fleet API and Teslemetry.
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api/pb2/universal_message_pb2.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{tesla_fleet_api-0.8.3 → tesla_fleet_api-0.8.5}/tesla_fleet_api.egg-info/dependency_links.txt
RENAMED
File without changes
|
File without changes
|