tesla-fleet-api 0.8.2__py3-none-any.whl → 0.8.4__py3-none-any.whl
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.
- tesla_fleet_api/const.py +1 -1
- tesla_fleet_api/exceptions.py +216 -21
- tesla_fleet_api/teslafleetapi.py +13 -6
- tesla_fleet_api/vehiclesigned.py +33 -38
- {tesla_fleet_api-0.8.2.dist-info → tesla_fleet_api-0.8.4.dist-info}/METADATA +1 -1
- {tesla_fleet_api-0.8.2.dist-info → tesla_fleet_api-0.8.4.dist-info}/RECORD +9 -9
- {tesla_fleet_api-0.8.2.dist-info → tesla_fleet_api-0.8.4.dist-info}/LICENSE +0 -0
- {tesla_fleet_api-0.8.2.dist-info → tesla_fleet_api-0.8.4.dist-info}/WHEEL +0 -0
- {tesla_fleet_api-0.8.2.dist-info → tesla_fleet_api-0.8.4.dist-info}/top_level.txt +0 -0
tesla_fleet_api/const.py
CHANGED
tesla_fleet_api/exceptions.py
CHANGED
@@ -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
|
tesla_fleet_api/teslafleetapi.py
CHANGED
@@ -30,7 +30,7 @@ class TeslaFleetApi:
|
|
30
30
|
session: aiohttp.ClientSession
|
31
31
|
headers: dict[str, str]
|
32
32
|
refresh_hook: Awaitable | None = None
|
33
|
-
|
33
|
+
private_key: ec.EllipticCurvePrivateKey | None = None
|
34
34
|
|
35
35
|
def __init__(
|
36
36
|
self,
|
@@ -161,14 +161,16 @@ 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
|
-
self.
|
169
|
+
self.private_key = ec.generate_private_key(
|
168
170
|
ec.SECP256R1(), default_backend()
|
169
171
|
)
|
170
172
|
# save the key
|
171
|
-
pem = self.
|
173
|
+
pem = self.private_key.private_bytes(
|
172
174
|
encoding=serialization.Encoding.PEM,
|
173
175
|
format=serialization.PrivateFormat.TraditionalOpenSSL,
|
174
176
|
encryption_algorithm=serialization.NoEncryption(),
|
@@ -189,5 +191,10 @@ class TeslaFleetApi:
|
|
189
191
|
|
190
192
|
if not isinstance(value, ec.EllipticCurvePrivateKey):
|
191
193
|
raise AssertionError("Loaded key is not an EllipticCurvePrivateKey")
|
192
|
-
self.
|
193
|
-
return self.
|
194
|
+
self.private_key = value
|
195
|
+
return self.private_key
|
196
|
+
|
197
|
+
@property
|
198
|
+
def has_private_key(self) -> bool:
|
199
|
+
"""Check if the private key has been set."""
|
200
|
+
return self.private_key is not None
|
tesla_fleet_api/vehiclesigned.py
CHANGED
@@ -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,
|
@@ -154,7 +154,7 @@ class Session:
|
|
154
154
|
class VehicleSigned(VehicleSpecific):
|
155
155
|
"""Class describing the Tesla Fleet API vehicle endpoints and commands for a specific vehicle with command signing."""
|
156
156
|
|
157
|
-
|
157
|
+
private_key: ec.EllipticCurvePrivateKey
|
158
158
|
_public_key: bytes
|
159
159
|
_from_destination: bytes
|
160
160
|
_sessions: dict[int, Session]
|
@@ -164,13 +164,13 @@ class VehicleSigned(VehicleSpecific):
|
|
164
164
|
):
|
165
165
|
super().__init__(parent, vin)
|
166
166
|
if key:
|
167
|
-
self.
|
168
|
-
elif parent._parent.
|
169
|
-
self.
|
167
|
+
self.private_key = key
|
168
|
+
elif parent._parent.private_key:
|
169
|
+
self.private_key = parent._parent.private_key
|
170
170
|
else:
|
171
171
|
raise ValueError("No private key.")
|
172
172
|
|
173
|
-
self._public_key = self.
|
173
|
+
self._public_key = self.private_key.public_key().public_bytes(
|
174
174
|
encoding=Encoding.X962, format=PublicFormat.UncompressedPoint
|
175
175
|
)
|
176
176
|
self._from_destination = randbytes(16)
|
@@ -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,10 +203,11 @@ 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
|
203
|
-
shared = self.
|
210
|
+
shared = self.private_key.exchange(
|
204
211
|
ec.ECDH(),
|
205
212
|
ec.EllipticCurvePublicKey.from_encoded_point(
|
206
213
|
ec.SECP256R1(), 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,19 +1,19 @@
|
|
1
1
|
tesla_fleet_api/__init__.py,sha256=BVZUDsfaxT05tAfcMHHWiyFyXwmDOx_wP_IHZBscgho,729
|
2
2
|
tesla_fleet_api/charging.py,sha256=N_mc8axrXj3iduqLj_jCt4Vx86tHqe3xqQT4R1R7HvU,1689
|
3
|
-
tesla_fleet_api/const.py,sha256=
|
3
|
+
tesla_fleet_api/const.py,sha256=LdClo7IxPtcVCtp_9eLnBHGm6eAQngPXlBqFCjbUsdA,9577
|
4
4
|
tesla_fleet_api/energy.py,sha256=S7D75MPuMVsHgkyUcFfMqjGCLZBM5YVFlWLEHbaX-zw,5957
|
5
5
|
tesla_fleet_api/energyspecific.py,sha256=UfeaGE59aoAa8UhpQCXUi0sOrNCA40xZlqwF73BXTVY,4254
|
6
|
-
tesla_fleet_api/exceptions.py,sha256=
|
6
|
+
tesla_fleet_api/exceptions.py,sha256=wteuynQA2OY13IHEsiQHV-WU8BPUCpDDHBaYbRvQlHI,20299
|
7
7
|
tesla_fleet_api/partner.py,sha256=1vIBUaxKLIfqcC0X6VXZN0dMAzj_CLNPUMjA6QVqZ1k,1223
|
8
8
|
tesla_fleet_api/ratecalculator.py,sha256=4lz8yruUeouHXh_3ezsXX-CTpIegp1T1J4VuRV_qdHA,1791
|
9
|
-
tesla_fleet_api/teslafleetapi.py,sha256=
|
9
|
+
tesla_fleet_api/teslafleetapi.py,sha256=4Rnh_HNZkIw54o9SYAaHsA8vY0pmk_bMncrLuJ8MtSk,7389
|
10
10
|
tesla_fleet_api/teslafleetoauth.py,sha256=OY9yRQuokYo3ts0C8Qb6Z-o9NNAGHbX9F5mHfAh50fo,4121
|
11
11
|
tesla_fleet_api/teslafleetopensource.py,sha256=TJfVPcqJlA1b3kMoGuLr-g5Gn8UDyYsTZhjvGY1MtIk,2007
|
12
12
|
tesla_fleet_api/teslemetry.py,sha256=Rl73BWYYJk1UWIhCPwywcXGRlkATYZrPz3LP-Covppw,3272
|
13
13
|
tesla_fleet_api/tessie.py,sha256=4dBYxe1G2v9JvJGRbb01wXrAmvWT4jOfV4f_VQE_vkE,2302
|
14
14
|
tesla_fleet_api/user.py,sha256=TZE2oh-n5zrhKXmGRuiNL9voKVODD7rBhGE_IObYVGA,1179
|
15
15
|
tesla_fleet_api/vehicle.py,sha256=W5Y_ok5PK7jtXsenWpMWJTS4RpLhRW-1AlTPv1a6R6A,31765
|
16
|
-
tesla_fleet_api/vehiclesigned.py,sha256=
|
16
|
+
tesla_fleet_api/vehiclesigned.py,sha256=kxcR_I5B6I8ZsE336d22QDlVNpfxkdvRnW38XolLBsw,38698
|
17
17
|
tesla_fleet_api/vehiclespecific.py,sha256=Nr4zZzfmIuw3RFYjQEX6c_xtYZgztMsN5ohVn-YEH0I,20600
|
18
18
|
tesla_fleet_api/pb2/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
19
19
|
tesla_fleet_api/pb2/__init__.pyi,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
@@ -25,8 +25,8 @@ tesla_fleet_api/pb2/signatures_pb2.py,sha256=5mdJUC8EC8kx1UxYrHK5XI3_7M6v7w2POH1
|
|
25
25
|
tesla_fleet_api/pb2/universal_message_pb2.py,sha256=F6-SkYXSuzWDsBvnGMg9k2pAIZv13v609qCPx7NSrdw,7254
|
26
26
|
tesla_fleet_api/pb2/vcsec_pb2.py,sha256=CMJ97e4Mm4p7NFcgybbCC2KJRcvtrcqmBy_pGycYhMo,26238
|
27
27
|
tesla_fleet_api/pb2/vehicle_pb2.py,sha256=P1V7Dqg3BBGZwODxTpZqtxLP6fGS_FNBqJcz_Fp0crs,2482
|
28
|
-
tesla_fleet_api-0.8.
|
29
|
-
tesla_fleet_api-0.8.
|
30
|
-
tesla_fleet_api-0.8.
|
31
|
-
tesla_fleet_api-0.8.
|
32
|
-
tesla_fleet_api-0.8.
|
28
|
+
tesla_fleet_api-0.8.4.dist-info/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
29
|
+
tesla_fleet_api-0.8.4.dist-info/METADATA,sha256=IgxXyOX1pquDCnzteGukMbnBUKIO9V95H2bP4xl67Hc,3821
|
30
|
+
tesla_fleet_api-0.8.4.dist-info/WHEEL,sha256=GV9aMThwP_4oNCtvEC2ec3qUYutgWeAzklro_0m4WJQ,91
|
31
|
+
tesla_fleet_api-0.8.4.dist-info/top_level.txt,sha256=jeNbog_1saXBFrGpom9WyPWmilxsyP3szL_G7JLWQfM,16
|
32
|
+
tesla_fleet_api-0.8.4.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|