tesla-fleet-api 0.4.0 → 0.6.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.
Files changed (215) hide show
  1. package/README.md +269 -1
  2. package/dist/_virtual/_rolldown/runtime.cjs +10 -0
  3. package/dist/bluetooth/adapters/shared.cjs +38 -0
  4. package/dist/bluetooth/adapters/shared.mjs +36 -0
  5. package/dist/bluetooth/async.cjs +121 -0
  6. package/dist/bluetooth/async.d.cts +10 -0
  7. package/dist/bluetooth/async.d.mts +10 -0
  8. package/dist/bluetooth/async.mjs +116 -0
  9. package/dist/bluetooth/broadcast.cjs +153 -0
  10. package/dist/bluetooth/broadcast.d.cts +59 -0
  11. package/dist/bluetooth/broadcast.d.mts +59 -0
  12. package/dist/bluetooth/broadcast.mjs +151 -0
  13. package/dist/bluetooth/constants.cjs +96 -0
  14. package/dist/bluetooth/constants.d.cts +68 -0
  15. package/dist/bluetooth/constants.d.mts +68 -0
  16. package/dist/bluetooth/constants.mjs +70 -0
  17. package/dist/bluetooth/framing.cjs +125 -0
  18. package/dist/bluetooth/framing.d.cts +45 -0
  19. package/dist/bluetooth/framing.d.mts +45 -0
  20. package/dist/bluetooth/framing.mjs +122 -0
  21. package/dist/bluetooth/homey.cjs +165 -0
  22. package/dist/bluetooth/homey.d.cts +84 -0
  23. package/dist/bluetooth/homey.d.mts +84 -0
  24. package/dist/bluetooth/homey.mjs +159 -0
  25. package/dist/bluetooth/names.cjs +24 -0
  26. package/dist/bluetooth/names.d.cts +10 -0
  27. package/dist/bluetooth/names.d.mts +10 -0
  28. package/dist/bluetooth/names.mjs +20 -0
  29. package/dist/bluetooth/noble.cjs +178 -0
  30. package/dist/bluetooth/noble.d.cts +58 -0
  31. package/dist/bluetooth/noble.d.mts +58 -0
  32. package/dist/bluetooth/noble.mjs +177 -0
  33. package/dist/bluetooth/streamglue.cjs +157 -0
  34. package/dist/bluetooth/streamglue.d.cts +37 -0
  35. package/dist/bluetooth/streamglue.d.mts +37 -0
  36. package/dist/bluetooth/streamglue.mjs +154 -0
  37. package/dist/bluetooth/teslabluetooth.cjs +67 -0
  38. package/dist/bluetooth/teslabluetooth.d.cts +41 -0
  39. package/dist/bluetooth/teslabluetooth.d.mts +41 -0
  40. package/dist/bluetooth/teslabluetooth.mjs +66 -0
  41. package/dist/bluetooth/transport.cjs +10 -0
  42. package/dist/bluetooth/transport.d.cts +97 -0
  43. package/dist/bluetooth/transport.d.mts +97 -0
  44. package/dist/bluetooth/transport.mjs +10 -0
  45. package/dist/bluetooth/vehiclebluetooth.cjs +1272 -0
  46. package/dist/bluetooth/vehiclebluetooth.d.cts +495 -0
  47. package/dist/bluetooth/vehiclebluetooth.d.mts +495 -0
  48. package/dist/bluetooth/vehiclebluetooth.mjs +1270 -0
  49. package/dist/bluetooth/verify.cjs +93 -0
  50. package/dist/bluetooth/verify.d.cts +35 -0
  51. package/dist/bluetooth/verify.d.mts +35 -0
  52. package/dist/bluetooth/verify.mjs +91 -0
  53. package/dist/bluetooth.cjs +52 -0
  54. package/dist/bluetooth.d.cts +10 -0
  55. package/dist/bluetooth.d.mts +10 -0
  56. package/dist/bluetooth.mjs +9 -0
  57. package/dist/commands.cjs +1080 -85
  58. package/dist/commands.d.cts +585 -54
  59. package/dist/commands.d.mts +583 -51
  60. package/dist/commands.mjs +1084 -93
  61. package/dist/const.cjs +22 -0
  62. package/dist/const.d.cts +21 -0
  63. package/dist/const.d.mts +21 -0
  64. package/dist/const.mjs +20 -1
  65. package/dist/energy.cjs +24 -19
  66. package/dist/energy.d.cts +21 -15
  67. package/dist/energy.d.mts +21 -15
  68. package/dist/energy.mjs +24 -19
  69. package/dist/energyisland.cjs +38 -0
  70. package/dist/energyisland.mjs +37 -0
  71. package/dist/energyparsers.cjs +118 -0
  72. package/dist/energyparsers.d.cts +39 -0
  73. package/dist/energyparsers.d.mts +39 -0
  74. package/dist/energyparsers.mjs +116 -0
  75. package/dist/energyspecific.cjs +375 -17
  76. package/dist/energyspecific.d.cts +199 -19
  77. package/dist/energyspecific.d.mts +197 -16
  78. package/dist/energyspecific.mjs +370 -18
  79. package/dist/exceptions.cjs +3 -2
  80. package/dist/exceptions.d.cts +3 -2
  81. package/dist/exceptions.d.mts +3 -2
  82. package/dist/exceptions.mjs +3 -2
  83. package/dist/funnel.cjs +297 -0
  84. package/dist/funnel.d.cts +118 -0
  85. package/dist/funnel.d.mts +118 -0
  86. package/dist/funnel.mjs +292 -0
  87. package/dist/index.cjs +61 -0
  88. package/dist/index.d.cts +22 -8
  89. package/dist/index.d.mts +22 -8
  90. package/dist/index.mjs +19 -6
  91. package/dist/log.cjs +75 -0
  92. package/dist/log.d.cts +4 -0
  93. package/dist/log.d.mts +4 -0
  94. package/dist/log.mjs +71 -0
  95. package/dist/oauth.cjs +143 -0
  96. package/dist/oauth.d.cts +69 -0
  97. package/dist/oauth.d.mts +69 -0
  98. package/dist/oauth.mjs +143 -0
  99. package/dist/powerwall/client.cjs +818 -0
  100. package/dist/powerwall/client.d.cts +297 -0
  101. package/dist/powerwall/client.d.mts +297 -0
  102. package/dist/powerwall/client.mjs +807 -0
  103. package/dist/powerwall/components.cjs +188 -0
  104. package/dist/powerwall/components.d.cts +45 -0
  105. package/dist/powerwall/components.d.mts +45 -0
  106. package/dist/powerwall/components.mjs +182 -0
  107. package/dist/powerwall/energysite.cjs +216 -0
  108. package/dist/powerwall/energysite.d.cts +104 -0
  109. package/dist/powerwall/energysite.d.mts +104 -0
  110. package/dist/powerwall/energysite.mjs +214 -0
  111. package/dist/powerwall/exceptions.cjs +59 -0
  112. package/dist/powerwall/exceptions.d.cts +38 -0
  113. package/dist/powerwall/exceptions.d.mts +38 -0
  114. package/dist/powerwall/exceptions.mjs +51 -0
  115. package/dist/powerwall/gateway.cjs +102 -0
  116. package/dist/powerwall/gateway.d.cts +57 -0
  117. package/dist/powerwall/gateway.d.mts +57 -0
  118. package/dist/powerwall/gateway.mjs +101 -0
  119. package/dist/powerwall/merge.cjs +163 -0
  120. package/dist/powerwall/merge.d.cts +63 -0
  121. package/dist/powerwall/merge.d.mts +63 -0
  122. package/dist/powerwall/merge.mjs +159 -0
  123. package/dist/powerwall/models.d.cts +95 -0
  124. package/dist/powerwall/models.d.mts +95 -0
  125. package/dist/powerwall/queries.cjs +17 -0
  126. package/dist/powerwall/queries.mjs +10 -0
  127. package/dist/powerwall/transport.cjs +232 -0
  128. package/dist/powerwall/transport.mjs +227 -0
  129. package/dist/powerwall.cjs +47 -0
  130. package/dist/powerwall.d.cts +9 -0
  131. package/dist/powerwall.d.mts +9 -0
  132. package/dist/powerwall.mjs +8 -0
  133. package/dist/router/base.cjs +203 -0
  134. package/dist/router/base.d.cts +112 -0
  135. package/dist/router/base.d.mts +112 -0
  136. package/dist/router/base.mjs +200 -0
  137. package/dist/router/energysite.cjs +65 -0
  138. package/dist/router/energysite.d.cts +47 -0
  139. package/dist/router/energysite.d.mts +47 -0
  140. package/dist/router/energysite.mjs +60 -0
  141. package/dist/router.cjs +13 -0
  142. package/dist/router.d.cts +3 -1
  143. package/dist/router.d.mts +3 -1
  144. package/dist/router.mjs +3 -1
  145. package/dist/signing/crypto.cjs +28 -0
  146. package/dist/signing/crypto.mjs +26 -1
  147. package/dist/signing/energy.cjs +123 -0
  148. package/dist/signing/energy.d.cts +45 -0
  149. package/dist/signing/energy.d.mts +45 -0
  150. package/dist/signing/energy.mjs +120 -0
  151. package/dist/signing/jws.cjs +229 -0
  152. package/dist/signing/jws.d.cts +45 -0
  153. package/dist/signing/jws.d.mts +45 -0
  154. package/dist/signing/jws.mjs +211 -0
  155. package/dist/signing/keys.cjs +191 -0
  156. package/dist/signing/keys.d.cts +21 -0
  157. package/dist/signing/keys.d.mts +21 -0
  158. package/dist/signing/keys.mjs +182 -0
  159. package/dist/signing/session.cjs +104 -30
  160. package/dist/signing/session.d.cts +60 -23
  161. package/dist/signing/session.d.mts +60 -23
  162. package/dist/signing/session.mjs +105 -31
  163. package/dist/tariff.cjs +27 -0
  164. package/dist/tariff.d.cts +11 -0
  165. package/dist/tariff.d.mts +11 -0
  166. package/dist/tariff.mjs +27 -1
  167. package/dist/teslafleetapi.cjs +256 -55
  168. package/dist/teslafleetapi.d.cts +110 -14
  169. package/dist/teslafleetapi.d.mts +110 -14
  170. package/dist/teslafleetapi.mjs +258 -57
  171. package/dist/teslemetry.cjs +152 -5
  172. package/dist/teslemetry.d.cts +95 -5
  173. package/dist/teslemetry.d.mts +93 -3
  174. package/dist/teslemetry.mjs +151 -6
  175. package/dist/teslemetryenergy.cjs +287 -0
  176. package/dist/teslemetryenergy.d.cts +154 -0
  177. package/dist/teslemetryenergy.d.mts +154 -0
  178. package/dist/teslemetryenergy.mjs +282 -0
  179. package/dist/teslemetryvehicle.cjs +407 -0
  180. package/dist/teslemetryvehicle.d.cts +238 -0
  181. package/dist/teslemetryvehicle.d.mts +238 -0
  182. package/dist/teslemetryvehicle.mjs +405 -0
  183. package/dist/tessie.cjs +42 -5
  184. package/dist/tessie.d.cts +51 -5
  185. package/dist/tessie.d.mts +49 -3
  186. package/dist/tessie.mjs +42 -5
  187. package/dist/tessievehicle.cjs +514 -0
  188. package/dist/tessievehicle.d.cts +333 -0
  189. package/dist/tessievehicle.d.mts +333 -0
  190. package/dist/tessievehicle.mjs +513 -0
  191. package/dist/types/live_status.d.cts +16 -16
  192. package/dist/types/live_status.d.mts +16 -16
  193. package/dist/types/responses.d.cts +5 -1
  194. package/dist/types/responses.d.mts +5 -1
  195. package/dist/types/vehicle.d.cts +7 -1
  196. package/dist/types/vehicle.d.mts +7 -1
  197. package/dist/types.d.cts +3 -3
  198. package/dist/types.d.mts +3 -3
  199. package/dist/util.cjs +41 -0
  200. package/dist/util.d.cts +18 -0
  201. package/dist/util.d.mts +18 -0
  202. package/dist/util.mjs +40 -0
  203. package/dist/vehicle.cjs +79 -36
  204. package/dist/vehicle.d.cts +42 -26
  205. package/dist/vehicle.d.mts +42 -26
  206. package/dist/vehicle.mjs +80 -37
  207. package/dist/vehiclesigned.cjs +20 -5
  208. package/dist/vehiclesigned.d.cts +14 -5
  209. package/dist/vehiclesigned.d.mts +14 -5
  210. package/dist/vehiclesigned.mjs +20 -5
  211. package/dist/vehiclespecific.cjs +126 -15
  212. package/dist/vehiclespecific.d.cts +82 -18
  213. package/dist/vehiclespecific.d.mts +82 -18
  214. package/dist/vehiclespecific.mjs +126 -15
  215. package/package.json +56 -3
@@ -1,31 +1,43 @@
1
1
  import TeslaFleetApi from "./teslafleetapi.mjs";
2
2
  import { CommandResponse, FleetTelemetryConfig } from "./types/commands.mjs";
3
- import { OptionsResponse } from "./types/responses.mjs";
4
- import { VehicleResponse } from "./types/vehicle.mjs";
3
+ import { OptionsResponse, ResponseEnvelope } from "./types/responses.mjs";
4
+ import { VehicleResponse, WakeUpOptions } from "./types/vehicle.mjs";
5
5
  import { AutoSeat, ClimateMode, Level, Seat, Trunk, VehicleDataEndpoint } from "./const.mjs";
6
6
  import { VehicleDataResponse } from "./types/vehicle_data.mjs";
7
7
  import VehicleSpecific from "./vehiclespecific.mjs";
8
8
  import VehicleSigned from "./vehiclesigned.mjs";
9
9
  export default class Vehicle {
10
+ #private;
11
+ /** Class `createFleet` instantiates; a subclass overrides it to supply its own vehicle type. */
12
+ static Fleet: new (parent: Vehicle, vin: string) => VehicleSpecific;
13
+ /** Class `createSigned` instantiates; a subclass overrides it to supply its own signed vehicle type. */
14
+ static Signed: new (parent: Vehicle, vin: string, private_key?: Buffer | false, public_key?: Buffer) => VehicleSigned;
10
15
  parent: TeslaFleetApi;
11
- /** Fallback private key for `signed()` when a call site doesn't pass one explicitly. */
12
- private_key?: Buffer;
16
+ /** Every vehicle created by this factory, keyed by VIN; the latest `create*` call for a VIN wins. */
17
+ byVin: Map<string, VehicleSpecific>;
13
18
  constructor(parent: TeslaFleetApi);
19
+ /** Fallback private key for `createSigned()` when a call site doesn't pass one explicitly. */
20
+ get private_key(): Buffer | undefined;
21
+ set private_key(key: Buffer | undefined);
14
22
  /**
15
- * Returns a class for a single vehicle.
23
+ * Creates a Fleet API vehicle that sends plaintext REST commands.
16
24
  * @param vin
17
25
  * @returns
18
26
  */
19
- specific(vin: string): VehicleSpecific;
27
+ createFleet(vin: string): VehicleSpecific;
20
28
  /**
21
- * Returns a class for a single vehicle that signs commands with the
22
- * Tesla Vehicle Command Protocol and dispatches them through the Fleet
23
- * API `/signed_command` endpoint, instead of the plaintext REST commands.
29
+ * Creates a Fleet API vehicle that signs commands with the Tesla Vehicle
30
+ * Command Protocol and dispatches them through the `/signed_command`
31
+ * endpoint, instead of the plaintext REST commands.
24
32
  * @param vin
25
- * @param private_key Raw 32-byte P-256 private key scalar. Falls back to `this.private_key`.
33
+ * @param private_key Raw 32-byte P-256 private key scalar. Falls back to `this.private_key`, then the client's `private_key`. `false` disables signing.
26
34
  * @param public_key Uncompressed P-256 public key point. Derived from `private_key` if omitted.
27
35
  */
28
- signed(vin: string, private_key?: Buffer, public_key?: Buffer): VehicleSigned;
36
+ createSigned(vin: string, private_key?: Buffer | false, public_key?: Buffer): VehicleSigned;
37
+ /** Legacy name for `createFleet`. */
38
+ specific(vin: string): VehicleSpecific;
39
+ /** Legacy name for `createSigned`. */
40
+ specificSigned(vin: string, private_key?: Buffer | false, public_key?: Buffer): VehicleSigned;
29
41
  /**
30
42
  * Return the vehicle model name
31
43
  * @param vin
@@ -43,7 +55,7 @@ export default class Vehicle {
43
55
  * @param vehicle_tag VIN or id field of a vehicle
44
56
  * @param which_trunk "front" or "rear"
45
57
  */
46
- actuate_truck(vehicle_tag: string | number, which_trunk: Trunk): Promise<CommandResponse>;
58
+ actuate_trunk(vehicle_tag: string | number, which_trunk: Trunk): Promise<CommandResponse>;
47
59
  /**
48
60
  * Adjusts vehicle media playback volume.
49
61
  * @param vehicle_tag VIN or id field of a vehicle
@@ -98,8 +110,9 @@ export default class Vehicle {
98
110
  /**
99
111
  * Deactivates PIN to Drive and resets the associated PIN for vehicles running firmware versions 2023.44+. This command is only accessible to fleet managers or owners.
100
112
  * @param vehicle_tag VIN or id field of a vehicle
113
+ * @param pin Optional four-digit PIN
101
114
  */
102
- clear_pin_to_drive_admin(vehicle_tag: string | number): Promise<CommandResponse>;
115
+ clear_pin_to_drive_admin(vehicle_tag: string | number, pin?: string | number): Promise<CommandResponse>;
103
116
  /**
104
117
  * Locks the vehicle.
105
118
  * @param vehicle_tag VIN or id field of a vehicle
@@ -172,11 +185,12 @@ export default class Vehicle {
172
185
  /**
173
186
  * Sends a location to the in-vehicle navigation system.
174
187
  * @param vehicle_tag VIN or id field of a vehicle
188
+ * @param value Destination text
175
189
  * @param type "share_ext_content_raw"
176
- * @param locale ISO locale such as "en-US"
177
- * @param timestamp_ms
190
+ * @param locale ISO locale such as "en-US". Defaults to `DEFAULT_LOCALE`.
191
+ * @param timestamp_ms Defaults to now
178
192
  */
179
- navigation_request(vehicle_tag: string | number, value: string, locale: string, type?: string): Promise<CommandResponse>;
193
+ navigation_request(vehicle_tag: string | number, value: string, type?: string, locale?: string | null, timestamp_ms?: number | null): Promise<CommandResponse>;
180
194
  /**
181
195
  * Start navigation to a supercharger.
182
196
  * @param vehicle_tag VIN or id field of a vehicle
@@ -210,7 +224,7 @@ export default class Vehicle {
210
224
  * @param seat_position Seat position
211
225
  * @param seat_cooler_level Cooling level
212
226
  */
213
- remote_seat_cooler_request(vehicle_tag: string | number, seat_position: Seat | number, seat_cooler_level: Level): Promise<CommandResponse>;
227
+ remote_seat_cooler_request(vehicle_tag: string | number, seat_position: keyof typeof AutoSeat | number, seat_cooler_level: Level): Promise<CommandResponse>;
214
228
  /**
215
229
  * Sets seat heating.
216
230
  * @param vehicle_tag VIN or id field of a vehicle
@@ -342,7 +356,7 @@ export default class Vehicle {
342
356
  * @param on `true` or `false`
343
357
  * @param password Four-digit passcode
344
358
  */
345
- set_valet_mode(vehicle_tag: string | number, on: boolean, password: string | number): Promise<CommandResponse>;
359
+ set_valet_mode(vehicle_tag: string | number, on: boolean, password?: string | number): Promise<CommandResponse>;
346
360
  /**
347
361
  * Changes the name of a vehicle. This command also requires the Tesla Vehicle Command Protocol - for more information, please see refer to the documentation here.
348
362
  * @param vehicle_tag VIN or id field of a vehicle
@@ -397,7 +411,7 @@ export default class Vehicle {
397
411
  * @param lat Latitude
398
412
  * @param lon Longitude
399
413
  */
400
- trigger_homelink(vehicle_tag: string | number, lat: number, lon: number, token?: string): Promise<CommandResponse>;
414
+ trigger_homelink(vehicle_tag: string | number, token?: string, lat?: number, lon?: number): Promise<CommandResponse>;
401
415
  /**
402
416
  * Upcoming calendar entries stored on the vehicle.
403
417
  * @param vehicle_tag VIN or id field of a vehicle
@@ -411,18 +425,18 @@ export default class Vehicle {
411
425
  * @param lat Latitude
412
426
  * @param lon Longitude
413
427
  */
414
- window_control(vehicle_tag: string | number, command: "vent" | "close", lat: number, lon: number): Promise<CommandResponse>;
428
+ window_control(vehicle_tag: string | number, command: "vent" | "close", lat?: number, lon?: number): Promise<CommandResponse>;
415
429
  /**
416
430
  * Returns all allowed drivers for a vehicle. This endpoint is only available for the vehicle owner.
417
431
  * @param vehicle_tag VIN or id field of a vehicle
418
432
  */
419
- drivers(vehicle_tag: string | number): Promise<Record<string, any>[]>;
433
+ drivers(vehicle_tag: string | number): Promise<ResponseEnvelope<Record<string, any>[]>>;
420
434
  /**
421
435
  * Removes driver access from a vehicle. Share users can only remove their own access. Owners can remove share access or their own.
422
436
  * @param vehicle_tag VIN or id field of a vehicle
423
437
  * @param share_user_id
424
438
  */
425
- drivers_remove(vehicle_tag: string | number, share_user_id?: number): Promise<Record<string, any>>;
439
+ drivers_remove(vehicle_tag: string | number, share_user_id?: string | number): Promise<Record<string, any>>;
426
440
  /**
427
441
  * Returns eligible vehicle subscriptions.
428
442
  * @param vin Vehicle Identification Number
@@ -444,7 +458,7 @@ export default class Vehicle {
444
458
  * @param config A dictionary description the fleet telemetry configuration
445
459
  * @returns
446
460
  */
447
- fleet_telemetry_config(config: FleetTelemetryConfig): Promise<Record<string, any>>;
461
+ fleet_telemetry_config_create(config: FleetTelemetryConfig): Promise<Record<string, any>>;
448
462
  /**
449
463
  * Disconnects vehicles to stream telemetry data to self hosted fleet-telemetry server.
450
464
  * @param vehicle_tag VIN or id field of a vehicle
@@ -529,18 +543,20 @@ export default class Vehicle {
529
543
  * Returns information about a vehicle.
530
544
  * @param vehicle_tag VIN or id field of a vehicle
531
545
  */
532
- vehicle(vehicle_tag: string | number): Promise<VehicleResponse>;
546
+ vehicle(vehicle_tag: string | number): Promise<ResponseEnvelope<VehicleResponse>>;
533
547
  /**
534
548
  * Makes a live call to the vehicle. This may return cached data if the vehicle is offline. For vehicles running firmware versions 2023.38+, location_data is required to fetch vehicle location. This will result in a location sharing icon to show on the vehicle UI.
535
549
  * @param vehicle_tag VIN or id field of a vehicle
536
550
  * @param endpoints
537
551
  */
538
- vehicle_data(vehicle_tag: string | number, endpoints?: VehicleDataEndpoint[] | string): Promise<VehicleDataResponse>;
552
+ vehicle_data(vehicle_tag: string | number, endpoints?: VehicleDataEndpoint[] | string): Promise<ResponseEnvelope<VehicleDataResponse>>;
539
553
  /**
540
554
  * Wakes the vehicle from sleep, which is a state to minimize idle energy consumption.
541
555
  * @param vehicle_tag VIN or id field of a vehicle
556
+ * @param options.wait Poll `vehicle()` until the vehicle reports `online`, raising `VehicleOffline` at the deadline
557
+ * @param options.timeoutMs Deadline for `wait`, in milliseconds (default 60000)
542
558
  */
543
- wake_up(vehicle_tag: string | number): Promise<Record<string, any>>;
559
+ wake_up(vehicle_tag: string | number, { wait, timeoutMs }?: WakeUpOptions): Promise<ResponseEnvelope<VehicleResponse>>;
544
560
  /**
545
561
  * Returns warranty details.
546
562
  * @param vin
package/dist/vehicle.mjs CHANGED
@@ -1,32 +1,59 @@
1
- import { AutoSeat, ClimateModes, Models, Seats } from "./const.mjs";
1
+ import { AutoSeat, ClimateModes, DEFAULT_LOCALE, Models, Seats } from "./const.mjs";
2
+ import { VehicleOffline } from "./exceptions.mjs";
2
3
  import VehicleSpecific from "./vehiclespecific.mjs";
3
4
  import VehicleSigned from "./vehiclesigned.mjs";
4
5
  // src/vehicle.ts
6
+ const WAKE_TIMEOUT_MS = 6e4;
7
+ const WAKE_POLL_MS = 5e3;
5
8
  var Vehicle = class {
9
+ /** Class `createFleet` instantiates; a subclass overrides it to supply its own vehicle type. */
10
+ static Fleet = VehicleSpecific;
11
+ /** Class `createSigned` instantiates; a subclass overrides it to supply its own signed vehicle type. */
12
+ static Signed = VehicleSigned;
6
13
  parent;
7
- /** Fallback private key for `signed()` when a call site doesn't pass one explicitly. */
8
- private_key;
14
+ #privateKey;
15
+ /** Every vehicle created by this factory, keyed by VIN; the latest `create*` call for a VIN wins. */
16
+ byVin = /* @__PURE__ */ new Map();
9
17
  constructor(parent) {
10
18
  this.parent = parent;
11
19
  }
20
+ /** Fallback private key for `createSigned()` when a call site doesn't pass one explicitly. */
21
+ get private_key() {
22
+ return this.#privateKey;
23
+ }
24
+ set private_key(key) {
25
+ this.#privateKey = key;
26
+ }
12
27
  /**
13
- * Returns a class for a single vehicle.
28
+ * Creates a Fleet API vehicle that sends plaintext REST commands.
14
29
  * @param vin
15
30
  * @returns
16
31
  */
17
- specific(vin) {
18
- return new VehicleSpecific(this, vin);
32
+ createFleet(vin) {
33
+ const vehicle = new this.constructor.Fleet(this, vin);
34
+ this.byVin.set(vin, vehicle);
35
+ return vehicle;
19
36
  }
20
37
  /**
21
- * Returns a class for a single vehicle that signs commands with the
22
- * Tesla Vehicle Command Protocol and dispatches them through the Fleet
23
- * API `/signed_command` endpoint, instead of the plaintext REST commands.
38
+ * Creates a Fleet API vehicle that signs commands with the Tesla Vehicle
39
+ * Command Protocol and dispatches them through the `/signed_command`
40
+ * endpoint, instead of the plaintext REST commands.
24
41
  * @param vin
25
- * @param private_key Raw 32-byte P-256 private key scalar. Falls back to `this.private_key`.
42
+ * @param private_key Raw 32-byte P-256 private key scalar. Falls back to `this.private_key`, then the client's `private_key`. `false` disables signing.
26
43
  * @param public_key Uncompressed P-256 public key point. Derived from `private_key` if omitted.
27
44
  */
28
- signed(vin, private_key, public_key) {
29
- return new VehicleSigned(this, vin, private_key, public_key);
45
+ createSigned(vin, private_key, public_key) {
46
+ const vehicle = new this.constructor.Signed(this, vin, private_key, public_key);
47
+ this.byVin.set(vin, vehicle);
48
+ return vehicle;
49
+ }
50
+ /** Legacy name for `createFleet`. */
51
+ specific(vin) {
52
+ return this.createFleet(vin);
53
+ }
54
+ /** Legacy name for `createSigned`. */
55
+ specificSigned(vin, private_key, public_key) {
56
+ return this.createSigned(vin, private_key, public_key);
30
57
  }
31
58
  /**
32
59
  * Return the vehicle model name
@@ -49,7 +76,7 @@ var Vehicle = class {
49
76
  * @param vehicle_tag VIN or id field of a vehicle
50
77
  * @param which_trunk "front" or "rear"
51
78
  */
52
- async actuate_truck(vehicle_tag, which_trunk) {
79
+ async actuate_trunk(vehicle_tag, which_trunk) {
53
80
  return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/actuate_trunk`, null, { which_trunk });
54
81
  }
55
82
  /**
@@ -127,9 +154,10 @@ var Vehicle = class {
127
154
  /**
128
155
  * Deactivates PIN to Drive and resets the associated PIN for vehicles running firmware versions 2023.44+. This command is only accessible to fleet managers or owners.
129
156
  * @param vehicle_tag VIN or id field of a vehicle
157
+ * @param pin Optional four-digit PIN
130
158
  */
131
- async clear_pin_to_drive_admin(vehicle_tag) {
132
- return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/clear_pin_to_drive_admin`);
159
+ async clear_pin_to_drive_admin(vehicle_tag, pin) {
160
+ return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/clear_pin_to_drive_admin`, null, { pin: pin == null ? void 0 : String(pin) });
133
161
  }
134
162
  /**
135
163
  * Locks the vehicle.
@@ -223,7 +251,7 @@ var Vehicle = class {
223
251
  * @param lon Longitude
224
252
  * @param order Order of multiple stops
225
253
  */
226
- async navigation_gps_request(vehicle_tag, lat, lon, order) {
254
+ async navigation_gps_request(vehicle_tag, lat, lon, order = 0) {
227
255
  return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/navigation_gps_request`, null, {
228
256
  lat,
229
257
  lon,
@@ -233,16 +261,17 @@ var Vehicle = class {
233
261
  /**
234
262
  * Sends a location to the in-vehicle navigation system.
235
263
  * @param vehicle_tag VIN or id field of a vehicle
264
+ * @param value Destination text
236
265
  * @param type "share_ext_content_raw"
237
- * @param locale ISO locale such as "en-US"
238
- * @param timestamp_ms
266
+ * @param locale ISO locale such as "en-US". Defaults to `DEFAULT_LOCALE`.
267
+ * @param timestamp_ms Defaults to now
239
268
  */
240
- async navigation_request(vehicle_tag, value, locale, type = "share_ext_content_raw") {
269
+ async navigation_request(vehicle_tag, value, type = "share_ext_content_raw", locale, timestamp_ms) {
241
270
  return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/navigation_request`, null, {
271
+ value: { "android.intent.extra.TEXT": value },
242
272
  type,
243
- locale,
244
- timestamp_ms: String(Date.now()),
245
- value: { "android.intent.extra.TEXT": value }
273
+ locale: locale || DEFAULT_LOCALE,
274
+ timestamp_ms: timestamp_ms || Date.now()
246
275
  });
247
276
  }
248
277
  /**
@@ -294,7 +323,7 @@ var Vehicle = class {
294
323
  * @param seat_cooler_level Cooling level
295
324
  */
296
325
  async remote_seat_cooler_request(vehicle_tag, seat_position, seat_cooler_level) {
297
- if (typeof seat_position === "string") seat_position = Seats[seat_position];
326
+ if (typeof seat_position === "string") seat_position = AutoSeat[seat_position];
298
327
  return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/remote_seat_cooler_request`, null, {
299
328
  seat_position,
300
329
  seat_cooler_level
@@ -309,8 +338,8 @@ var Vehicle = class {
309
338
  async remote_seat_heater_request(vehicle_tag, seat_position, seat_heater_level) {
310
339
  if (typeof seat_position === "string") seat_position = Seats[seat_position];
311
340
  return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/remote_seat_heater_request`, null, {
312
- seat_position,
313
- seat_heater_level
341
+ heater: seat_position,
342
+ level: seat_heater_level
314
343
  });
315
344
  }
316
345
  /**
@@ -505,7 +534,7 @@ var Vehicle = class {
505
534
  async set_valet_mode(vehicle_tag, on, password) {
506
535
  return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/set_valet_mode`, null, {
507
536
  on,
508
- password: String(password)
537
+ password: password == null ? void 0 : String(password)
509
538
  });
510
539
  }
511
540
  /**
@@ -578,11 +607,14 @@ var Vehicle = class {
578
607
  * @param lat Latitude
579
608
  * @param lon Longitude
580
609
  */
581
- async trigger_homelink(vehicle_tag, lat, lon, token) {
582
- return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/trigger_homelink`, null, {
583
- token,
610
+ async trigger_homelink(vehicle_tag, token, lat, lon) {
611
+ const location = lat != null && lon != null ? {
584
612
  lat,
585
613
  lon
614
+ } : {};
615
+ return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/command/trigger_homelink`, null, {
616
+ token: token || void 0,
617
+ ...location
586
618
  });
587
619
  }
588
620
  /**
@@ -612,7 +644,7 @@ var Vehicle = class {
612
644
  * @param vehicle_tag VIN or id field of a vehicle
613
645
  */
614
646
  async drivers(vehicle_tag) {
615
- return this.parent._request("GET", `api/1/vehicles/${vehicle_tag}/drivers`).then(({ response }) => response);
647
+ return this.parent._request("GET", `api/1/vehicles/${vehicle_tag}/drivers`);
616
648
  }
617
649
  /**
618
650
  * Removes driver access from a vehicle. Share users can only remove their own access. Owners can remove share access or their own.
@@ -620,7 +652,7 @@ var Vehicle = class {
620
652
  * @param share_user_id
621
653
  */
622
654
  async drivers_remove(vehicle_tag, share_user_id) {
623
- return this.parent._request("DELETE", `api/1/vehicles/${vehicle_tag}/drivers`, null, { share_user_id });
655
+ return this.parent._request("DELETE", `api/1/vehicles/${vehicle_tag}/drivers`, { share_user_id });
624
656
  }
625
657
  /**
626
658
  * Returns eligible vehicle subscriptions.
@@ -649,7 +681,7 @@ var Vehicle = class {
649
681
  * @param config A dictionary description the fleet telemetry configuration
650
682
  * @returns
651
683
  */
652
- async fleet_telemetry_config(config) {
684
+ async fleet_telemetry_config_create(config) {
653
685
  return this.parent._request("POST", "api/1/vehicles/fleet_telemetry_config", null, config);
654
686
  }
655
687
  /**
@@ -775,7 +807,7 @@ var Vehicle = class {
775
807
  * @param vehicle_tag VIN or id field of a vehicle
776
808
  */
777
809
  async vehicle(vehicle_tag) {
778
- return this.parent._request("GET", `api/1/vehicles/${vehicle_tag}`).then(({ response }) => response);
810
+ return this.parent._request("GET", `api/1/vehicles/${vehicle_tag}`);
779
811
  }
780
812
  /**
781
813
  * Makes a live call to the vehicle. This may return cached data if the vehicle is offline. For vehicles running firmware versions 2023.38+, location_data is required to fetch vehicle location. This will result in a location sharing icon to show on the vehicle UI.
@@ -784,14 +816,25 @@ var Vehicle = class {
784
816
  */
785
817
  async vehicle_data(vehicle_tag, endpoints) {
786
818
  if (typeof endpoints === "object") endpoints = endpoints.join(";");
787
- return this.parent._request("GET", `api/1/vehicles/${vehicle_tag}/vehicle_data`, { endpoints }).then(({ response }) => response);
819
+ return this.parent._request("GET", `api/1/vehicles/${vehicle_tag}/vehicle_data`, { endpoints });
788
820
  }
789
821
  /**
790
822
  * Wakes the vehicle from sleep, which is a state to minimize idle energy consumption.
791
823
  * @param vehicle_tag VIN or id field of a vehicle
792
- */
793
- async wake_up(vehicle_tag) {
794
- return this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/wake_up`);
824
+ * @param options.wait Poll `vehicle()` until the vehicle reports `online`, raising `VehicleOffline` at the deadline
825
+ * @param options.timeoutMs Deadline for `wait`, in milliseconds (default 60000)
826
+ */
827
+ async wake_up(vehicle_tag, { wait = false, timeoutMs = WAKE_TIMEOUT_MS } = {}) {
828
+ const deadline = Date.now() + timeoutMs;
829
+ let result = await this.parent._request("POST", `api/1/vehicles/${vehicle_tag}/wake_up`);
830
+ if (!wait) return result;
831
+ while (result.response?.state !== "online") {
832
+ const remaining = deadline - Date.now();
833
+ if (remaining <= 0) throw new VehicleOffline(result);
834
+ await new Promise((resolve) => setTimeout(resolve, Math.min(WAKE_POLL_MS, remaining)));
835
+ result = await this.vehicle(vehicle_tag);
836
+ }
837
+ return result;
795
838
  }
796
839
  /**
797
840
  * Returns warranty details.
@@ -4,16 +4,31 @@ let _teslemetry_tesla_protocol_command_universal_message = require("@teslemetry/
4
4
  /**
5
5
  * The Fleet API `/signed_command` transport: fills `Commands`'s abstract
6
6
  * `_send` seam by base64-encoding the signed `RoutableMessage`, POSTing it to
7
- * the cloud `signed_command` endpoint, and decoding the reply. A future BLE
8
- * transport (Story 3) fills the same seam over a GATT link instead - nothing
9
- * else in `Commands` needs to change for that to work.
7
+ * the cloud `signed_command` endpoint, and decoding the reply. Replies here are
8
+ * singular and delivered whole, with no broadcast side channel, so `_send`
9
+ * has no use for `requires` or its options.
10
10
  */
11
11
  var VehicleSigned = class extends require_commands.default {
12
- async _send(msg, _requires, _expectsData, _confirmBroadcast) {
12
+ _transport_name = "fleet";
13
+ /**
14
+ * Configures fleet telemetry via `fleet_telemetry_config_jws`, signing
15
+ * `config` as a Tesla.SS256 JWS with this vehicle's command key, as Tesla's
16
+ * vehicle-command proxy does. Any `iss` or `aud` in `config` is overwritten.
17
+ * @param config The config for this vehicle, or `{ vins, config }` as in Python.
18
+ * @throws SigningDisabled when this vehicle has no key.
19
+ */
20
+ async fleet_telemetry_config_create(config) {
21
+ const { vins, config: claims } = "vins" in config ? config : {
22
+ vins: [this.vin],
23
+ config
24
+ };
25
+ return this.fleet_telemetry_config_jws(vins, this.signFleetTelemetryConfig(claims));
26
+ }
27
+ async _send(msg) {
13
28
  const encoded = Buffer.from(_teslemetry_tesla_protocol_command_universal_message.RoutableMessage.encode(msg).finish()).toString("base64");
14
29
  const json = await this.parent.signed_command(this.vin, encoded);
15
30
  const resp = _teslemetry_tesla_protocol_command_universal_message.RoutableMessage.decode(Buffer.from(json.response, "base64"));
16
- this.validateAndUpdateSession(resp, Buffer.from(msg.uuid));
31
+ this.validate_msg(resp, Buffer.from(msg.uuid), msg.toDestination?.domain);
17
32
  return resp;
18
33
  }
19
34
  };
@@ -1,14 +1,23 @@
1
1
  import Commands from "./commands.cjs";
2
+ import { FleetTelemetryConfig } from "./types/commands.cjs";
2
3
  import { RoutableMessage } from "@teslemetry/tesla-protocol/command/universal_message";
3
- import { VehicleStatus } from "@teslemetry/tesla-protocol/command/vcsec";
4
4
  /**
5
5
  * The Fleet API `/signed_command` transport: fills `Commands`'s abstract
6
6
  * `_send` seam by base64-encoding the signed `RoutableMessage`, POSTing it to
7
- * the cloud `signed_command` endpoint, and decoding the reply. A future BLE
8
- * transport (Story 3) fills the same seam over a GATT link instead - nothing
9
- * else in `Commands` needs to change for that to work.
7
+ * the cloud `signed_command` endpoint, and decoding the reply. Replies here are
8
+ * singular and delivered whole, with no broadcast side channel, so `_send`
9
+ * has no use for `requires` or its options.
10
10
  */
11
11
  declare class VehicleSigned extends Commands {
12
- protected _send(msg: RoutableMessage, _requires: string, _expectsData?: boolean, _confirmBroadcast?: (status: VehicleStatus) => boolean): Promise<RoutableMessage>;
12
+ readonly _transport_name: string;
13
+ /**
14
+ * Configures fleet telemetry via `fleet_telemetry_config_jws`, signing
15
+ * `config` as a Tesla.SS256 JWS with this vehicle's command key, as Tesla's
16
+ * vehicle-command proxy does. Any `iss` or `aud` in `config` is overwritten.
17
+ * @param config The config for this vehicle, or `{ vins, config }` as in Python.
18
+ * @throws SigningDisabled when this vehicle has no key.
19
+ */
20
+ fleet_telemetry_config_create(config: FleetTelemetryConfig | FleetTelemetryConfig["config"]): Promise<Record<string, any>>;
21
+ protected _send(msg: RoutableMessage): Promise<RoutableMessage>;
13
22
  }
14
23
  export = VehicleSigned;
@@ -1,13 +1,22 @@
1
1
  import Commands from "./commands.mjs";
2
+ import { FleetTelemetryConfig } from "./types/commands.mjs";
2
3
  import { RoutableMessage } from "@teslemetry/tesla-protocol/command/universal_message";
3
- import { VehicleStatus } from "@teslemetry/tesla-protocol/command/vcsec";
4
4
  /**
5
5
  * The Fleet API `/signed_command` transport: fills `Commands`'s abstract
6
6
  * `_send` seam by base64-encoding the signed `RoutableMessage`, POSTing it to
7
- * the cloud `signed_command` endpoint, and decoding the reply. A future BLE
8
- * transport (Story 3) fills the same seam over a GATT link instead - nothing
9
- * else in `Commands` needs to change for that to work.
7
+ * the cloud `signed_command` endpoint, and decoding the reply. Replies here are
8
+ * singular and delivered whole, with no broadcast side channel, so `_send`
9
+ * has no use for `requires` or its options.
10
10
  */
11
11
  export default class VehicleSigned extends Commands {
12
- protected _send(msg: RoutableMessage, _requires: string, _expectsData?: boolean, _confirmBroadcast?: (status: VehicleStatus) => boolean): Promise<RoutableMessage>;
12
+ readonly _transport_name: string;
13
+ /**
14
+ * Configures fleet telemetry via `fleet_telemetry_config_jws`, signing
15
+ * `config` as a Tesla.SS256 JWS with this vehicle's command key, as Tesla's
16
+ * vehicle-command proxy does. Any `iss` or `aud` in `config` is overwritten.
17
+ * @param config The config for this vehicle, or `{ vins, config }` as in Python.
18
+ * @throws SigningDisabled when this vehicle has no key.
19
+ */
20
+ fleet_telemetry_config_create(config: FleetTelemetryConfig | FleetTelemetryConfig["config"]): Promise<Record<string, any>>;
21
+ protected _send(msg: RoutableMessage): Promise<RoutableMessage>;
13
22
  }
@@ -4,16 +4,31 @@ import { RoutableMessage } from "@teslemetry/tesla-protocol/command/universal_me
4
4
  /**
5
5
  * The Fleet API `/signed_command` transport: fills `Commands`'s abstract
6
6
  * `_send` seam by base64-encoding the signed `RoutableMessage`, POSTing it to
7
- * the cloud `signed_command` endpoint, and decoding the reply. A future BLE
8
- * transport (Story 3) fills the same seam over a GATT link instead - nothing
9
- * else in `Commands` needs to change for that to work.
7
+ * the cloud `signed_command` endpoint, and decoding the reply. Replies here are
8
+ * singular and delivered whole, with no broadcast side channel, so `_send`
9
+ * has no use for `requires` or its options.
10
10
  */
11
11
  var VehicleSigned = class extends Commands {
12
- async _send(msg, _requires, _expectsData, _confirmBroadcast) {
12
+ _transport_name = "fleet";
13
+ /**
14
+ * Configures fleet telemetry via `fleet_telemetry_config_jws`, signing
15
+ * `config` as a Tesla.SS256 JWS with this vehicle's command key, as Tesla's
16
+ * vehicle-command proxy does. Any `iss` or `aud` in `config` is overwritten.
17
+ * @param config The config for this vehicle, or `{ vins, config }` as in Python.
18
+ * @throws SigningDisabled when this vehicle has no key.
19
+ */
20
+ async fleet_telemetry_config_create(config) {
21
+ const { vins, config: claims } = "vins" in config ? config : {
22
+ vins: [this.vin],
23
+ config
24
+ };
25
+ return this.fleet_telemetry_config_jws(vins, this.signFleetTelemetryConfig(claims));
26
+ }
27
+ async _send(msg) {
13
28
  const encoded = Buffer.from(RoutableMessage.encode(msg).finish()).toString("base64");
14
29
  const json = await this.parent.signed_command(this.vin, encoded);
15
30
  const resp = RoutableMessage.decode(Buffer.from(json.response, "base64"));
16
- this.validateAndUpdateSession(resp, Buffer.from(msg.uuid));
31
+ this.validate_msg(resp, Buffer.from(msg.uuid), msg.toDestination?.domain);
17
32
  return resp;
18
33
  }
19
34
  };