tesla-fleet-api 0.3.0 → 0.5.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.
- package/README.md +284 -1
- package/dist/_virtual/_rolldown/runtime.cjs +32 -0
- package/dist/_virtual/_rolldown/runtime.mjs +12 -0
- package/dist/bluetooth/adapters/shared.cjs +38 -0
- package/dist/bluetooth/adapters/shared.mjs +36 -0
- package/dist/bluetooth/async.cjs +121 -0
- package/dist/bluetooth/async.d.cts +10 -0
- package/dist/bluetooth/async.d.mts +10 -0
- package/dist/bluetooth/async.mjs +116 -0
- package/dist/bluetooth/broadcast.cjs +153 -0
- package/dist/bluetooth/broadcast.d.cts +59 -0
- package/dist/bluetooth/broadcast.d.mts +59 -0
- package/dist/bluetooth/broadcast.mjs +151 -0
- package/dist/bluetooth/constants.cjs +99 -0
- package/dist/bluetooth/constants.d.cts +70 -0
- package/dist/bluetooth/constants.d.mts +70 -0
- package/dist/bluetooth/constants.mjs +72 -0
- package/dist/bluetooth/esphome.cjs +292 -0
- package/dist/bluetooth/esphome.d.cts +83 -0
- package/dist/bluetooth/esphome.d.mts +83 -0
- package/dist/bluetooth/esphome.mjs +291 -0
- package/dist/bluetooth/framing.cjs +125 -0
- package/dist/bluetooth/framing.d.cts +45 -0
- package/dist/bluetooth/framing.d.mts +45 -0
- package/dist/bluetooth/framing.mjs +122 -0
- package/dist/bluetooth/homey.cjs +155 -0
- package/dist/bluetooth/homey.d.cts +75 -0
- package/dist/bluetooth/homey.d.mts +75 -0
- package/dist/bluetooth/homey.mjs +150 -0
- package/dist/bluetooth/names.cjs +24 -0
- package/dist/bluetooth/names.d.cts +10 -0
- package/dist/bluetooth/names.d.mts +10 -0
- package/dist/bluetooth/names.mjs +20 -0
- package/dist/bluetooth/noble.cjs +178 -0
- package/dist/bluetooth/noble.d.cts +58 -0
- package/dist/bluetooth/noble.d.mts +58 -0
- package/dist/bluetooth/noble.mjs +177 -0
- package/dist/bluetooth/streamglue.cjs +157 -0
- package/dist/bluetooth/streamglue.d.cts +37 -0
- package/dist/bluetooth/streamglue.d.mts +37 -0
- package/dist/bluetooth/streamglue.mjs +154 -0
- package/dist/bluetooth/teslabluetooth.cjs +67 -0
- package/dist/bluetooth/teslabluetooth.d.cts +41 -0
- package/dist/bluetooth/teslabluetooth.d.mts +41 -0
- package/dist/bluetooth/teslabluetooth.mjs +66 -0
- package/dist/bluetooth/transport.cjs +10 -0
- package/dist/bluetooth/transport.d.cts +95 -0
- package/dist/bluetooth/transport.d.mts +95 -0
- package/dist/bluetooth/transport.mjs +10 -0
- package/dist/bluetooth/vehiclebluetooth.cjs +1272 -0
- package/dist/bluetooth/vehiclebluetooth.d.cts +495 -0
- package/dist/bluetooth/vehiclebluetooth.d.mts +495 -0
- package/dist/bluetooth/vehiclebluetooth.mjs +1270 -0
- package/dist/bluetooth/verify.cjs +93 -0
- package/dist/bluetooth/verify.d.cts +35 -0
- package/dist/bluetooth/verify.d.mts +35 -0
- package/dist/bluetooth/verify.mjs +91 -0
- package/dist/bluetooth.cjs +53 -0
- package/dist/bluetooth.d.cts +10 -0
- package/dist/bluetooth.d.mts +10 -0
- package/dist/bluetooth.mjs +9 -0
- package/dist/charging.cjs +53 -0
- package/dist/charging.d.cts +31 -0
- package/dist/charging.d.mts +30 -0
- package/dist/charging.mjs +53 -0
- package/dist/commands.cjs +1797 -0
- package/dist/commands.d.cts +881 -0
- package/dist/commands.d.mts +881 -0
- package/dist/commands.mjs +1791 -0
- package/dist/const.cjs +322 -0
- package/dist/const.d.cts +308 -0
- package/dist/const.d.mts +308 -0
- package/dist/const.mjs +282 -0
- package/dist/energy.cjs +142 -0
- package/dist/energy.d.cts +101 -0
- package/dist/energy.d.mts +100 -0
- package/dist/energy.mjs +142 -0
- package/dist/energyisland.cjs +38 -0
- package/dist/energyisland.mjs +37 -0
- package/dist/energyparsers.cjs +118 -0
- package/dist/energyparsers.d.cts +39 -0
- package/dist/energyparsers.d.mts +39 -0
- package/dist/energyparsers.mjs +116 -0
- package/dist/energyspecific.cjs +457 -0
- package/dist/energyspecific.d.cts +258 -0
- package/dist/energyspecific.d.mts +258 -0
- package/dist/energyspecific.mjs +451 -0
- package/dist/exceptions.cjs +1488 -0
- package/dist/exceptions.d.cts +1143 -0
- package/dist/exceptions.d.mts +1143 -0
- package/dist/exceptions.mjs +1325 -0
- package/dist/funnel.cjs +297 -0
- package/dist/funnel.d.cts +118 -0
- package/dist/funnel.d.mts +118 -0
- package/dist/funnel.mjs +292 -0
- package/dist/index.cjs +287 -0
- package/dist/index.d.cts +28 -0
- package/dist/index.d.mts +28 -0
- package/dist/index.mjs +27 -0
- package/dist/log.cjs +75 -0
- package/dist/log.d.cts +4 -0
- package/dist/log.d.mts +4 -0
- package/dist/log.mjs +71 -0
- package/dist/oauth.cjs +143 -0
- package/dist/oauth.d.cts +69 -0
- package/dist/oauth.d.mts +69 -0
- package/dist/oauth.mjs +143 -0
- package/dist/partner.cjs +32 -0
- package/dist/partner.d.cts +24 -0
- package/dist/partner.d.mts +23 -0
- package/dist/partner.mjs +32 -0
- package/dist/powerwall/client.cjs +818 -0
- package/dist/powerwall/client.d.cts +297 -0
- package/dist/powerwall/client.d.mts +297 -0
- package/dist/powerwall/client.mjs +807 -0
- package/dist/powerwall/components.cjs +188 -0
- package/dist/powerwall/components.d.cts +45 -0
- package/dist/powerwall/components.d.mts +45 -0
- package/dist/powerwall/components.mjs +182 -0
- package/dist/powerwall/energysite.cjs +216 -0
- package/dist/powerwall/energysite.d.cts +104 -0
- package/dist/powerwall/energysite.d.mts +104 -0
- package/dist/powerwall/energysite.mjs +214 -0
- package/dist/powerwall/exceptions.cjs +59 -0
- package/dist/powerwall/exceptions.d.cts +38 -0
- package/dist/powerwall/exceptions.d.mts +38 -0
- package/dist/powerwall/exceptions.mjs +51 -0
- package/dist/powerwall/gateway.cjs +102 -0
- package/dist/powerwall/gateway.d.cts +57 -0
- package/dist/powerwall/gateway.d.mts +57 -0
- package/dist/powerwall/gateway.mjs +101 -0
- package/dist/powerwall/merge.cjs +163 -0
- package/dist/powerwall/merge.d.cts +63 -0
- package/dist/powerwall/merge.d.mts +63 -0
- package/dist/powerwall/merge.mjs +159 -0
- package/dist/powerwall/models.d.cts +95 -0
- package/dist/powerwall/models.d.mts +95 -0
- package/dist/powerwall/queries.cjs +17 -0
- package/dist/powerwall/queries.mjs +10 -0
- package/dist/powerwall/transport.cjs +232 -0
- package/dist/powerwall/transport.mjs +227 -0
- package/dist/powerwall.cjs +47 -0
- package/dist/powerwall.d.cts +9 -0
- package/dist/powerwall.d.mts +9 -0
- package/dist/powerwall.mjs +8 -0
- package/dist/router/base.cjs +203 -0
- package/dist/router/base.d.cts +112 -0
- package/dist/router/base.d.mts +112 -0
- package/dist/router/base.mjs +200 -0
- package/dist/router/energysite.cjs +65 -0
- package/dist/router/energysite.d.cts +47 -0
- package/dist/router/energysite.d.mts +47 -0
- package/dist/router/energysite.mjs +60 -0
- package/dist/router.cjs +13 -0
- package/dist/router.d.cts +3 -0
- package/dist/router.d.mts +3 -0
- package/dist/router.mjs +3 -0
- package/dist/signing/crypto.cjs +59 -0
- package/dist/signing/crypto.mjs +52 -0
- package/dist/signing/energy.cjs +123 -0
- package/dist/signing/energy.d.cts +45 -0
- package/dist/signing/energy.d.mts +45 -0
- package/dist/signing/energy.mjs +120 -0
- package/dist/signing/jws.cjs +229 -0
- package/dist/signing/jws.d.cts +45 -0
- package/dist/signing/jws.d.mts +45 -0
- package/dist/signing/jws.mjs +211 -0
- package/dist/signing/keys.cjs +191 -0
- package/dist/signing/keys.d.cts +21 -0
- package/dist/signing/keys.d.mts +21 -0
- package/dist/signing/keys.mjs +182 -0
- package/dist/signing/session.cjs +186 -0
- package/dist/signing/session.d.cts +106 -0
- package/dist/signing/session.d.mts +106 -0
- package/dist/signing/session.mjs +184 -0
- package/dist/tariff.cjs +319 -0
- package/dist/tariff.d.cts +40 -0
- package/dist/tariff.d.mts +40 -0
- package/dist/tariff.mjs +317 -0
- package/dist/teslafleetapi.cjs +326 -0
- package/dist/teslafleetapi.d.cts +160 -0
- package/dist/teslafleetapi.d.mts +160 -0
- package/dist/teslafleetapi.mjs +326 -0
- package/dist/teslemetry.cjs +183 -0
- package/dist/teslemetry.d.cts +113 -0
- package/dist/teslemetry.d.mts +113 -0
- package/dist/teslemetry.mjs +181 -0
- package/dist/teslemetryenergy.cjs +287 -0
- package/dist/teslemetryenergy.d.cts +154 -0
- package/dist/teslemetryenergy.d.mts +154 -0
- package/dist/teslemetryenergy.mjs +282 -0
- package/dist/teslemetryvehicle.cjs +407 -0
- package/dist/teslemetryvehicle.d.cts +238 -0
- package/dist/teslemetryvehicle.d.mts +238 -0
- package/dist/teslemetryvehicle.mjs +405 -0
- package/dist/tessie.cjs +71 -0
- package/dist/tessie.d.cts +69 -0
- package/dist/tessie.d.mts +69 -0
- package/dist/tessie.mjs +71 -0
- package/dist/tessievehicle.cjs +514 -0
- package/dist/tessievehicle.d.cts +333 -0
- package/dist/tessievehicle.d.mts +333 -0
- package/dist/tessievehicle.mjs +513 -0
- package/dist/types/commands.d.cts +28 -0
- package/dist/types/commands.d.mts +28 -0
- package/dist/types/live_status.d.cts +30 -0
- package/dist/types/live_status.d.mts +30 -0
- package/dist/types/products.d.cts +58 -0
- package/dist/types/products.d.mts +58 -0
- package/dist/types/responses.d.cts +13 -0
- package/dist/types/responses.d.mts +13 -0
- package/dist/types/site_info.d.cts +154 -0
- package/dist/types/site_info.d.mts +154 -0
- package/dist/types/vehicle.d.cts +33 -0
- package/dist/types/vehicle.d.mts +33 -0
- package/dist/types/vehicle_data.d.cts +278 -0
- package/dist/types/vehicle_data.d.mts +278 -0
- package/dist/types.cjs +0 -0
- package/dist/types.d.cts +9 -0
- package/dist/types.d.mts +9 -0
- package/dist/types.mjs +1 -0
- package/dist/user.cjs +28 -0
- package/dist/user.d.cts +17 -0
- package/dist/user.d.mts +16 -0
- package/dist/user.mjs +28 -0
- package/dist/util.cjs +41 -0
- package/dist/util.d.cts +18 -0
- package/dist/util.d.mts +18 -0
- package/dist/util.mjs +40 -0
- package/dist/vehicle.cjs +847 -0
- package/dist/vehicle.d.cts +566 -0
- package/dist/vehicle.d.mts +565 -0
- package/dist/vehicle.mjs +847 -0
- package/dist/vehiclesigned.cjs +35 -0
- package/dist/vehiclesigned.d.cts +23 -0
- package/dist/vehiclesigned.d.mts +22 -0
- package/dist/vehiclesigned.mjs +35 -0
- package/dist/vehiclespecific.cjs +715 -0
- package/dist/vehiclespecific.d.cts +497 -0
- package/dist/vehiclespecific.d.mts +496 -0
- package/dist/vehiclespecific.mjs +715 -0
- package/package.json +178 -38
- package/dist/charging.d.ts +0 -30
- package/dist/charging.js +0 -51
- package/dist/charging.js.map +0 -1
- package/dist/commands.d.ts +0 -352
- package/dist/commands.js +0 -875
- package/dist/commands.js.map +0 -1
- package/dist/energy.d.ts +0 -94
- package/dist/energy.js +0 -125
- package/dist/energy.js.map +0 -1
- package/dist/energyspecific.d.ts +0 -77
- package/dist/energyspecific.js +0 -97
- package/dist/energyspecific.js.map +0 -1
- package/dist/helpers.d.ts +0 -2
- package/dist/helpers.js +0 -10
- package/dist/helpers.js.map +0 -1
- package/dist/index.d.ts +0 -15
- package/dist/index.js +0 -15
- package/dist/index.js.map +0 -1
- package/dist/partner.d.ts +0 -23
- package/dist/partner.js +0 -31
- package/dist/partner.js.map +0 -1
- package/dist/signing/crypto.d.ts +0 -10
- package/dist/signing/crypto.js +0 -26
- package/dist/signing/crypto.js.map +0 -1
- package/dist/signing/errors.d.ts +0 -29
- package/dist/signing/errors.js +0 -40
- package/dist/signing/errors.js.map +0 -1
- package/dist/signing/session.d.ts +0 -69
- package/dist/signing/session.js +0 -102
- package/dist/signing/session.js.map +0 -1
- package/dist/tariff.d.ts +0 -29
- package/dist/tariff.js +0 -302
- package/dist/tariff.js.map +0 -1
- package/dist/teslafleetapi.d.ts +0 -58
- package/dist/teslafleetapi.js +0 -120
- package/dist/teslafleetapi.js.map +0 -1
- package/dist/teslemetry.d.ts +0 -29
- package/dist/teslemetry.js +0 -39
- package/dist/teslemetry.js.map +0 -1
- package/dist/tessie.d.ts +0 -23
- package/dist/tessie.js +0 -28
- package/dist/tessie.js.map +0 -1
- package/dist/types/commands.d.ts +0 -44
- package/dist/types/commands.js +0 -11
- package/dist/types/commands.js.map +0 -1
- package/dist/types/live_status.d.ts +0 -26
- package/dist/types/live_status.js +0 -2
- package/dist/types/live_status.js.map +0 -1
- package/dist/types/products.d.ts +0 -54
- package/dist/types/products.js +0 -2
- package/dist/types/products.js.map +0 -1
- package/dist/types/responses.d.ts +0 -5
- package/dist/types/responses.js +0 -2
- package/dist/types/responses.js.map +0 -1
- package/dist/types/site_info.d.ts +0 -150
- package/dist/types/site_info.js +0 -2
- package/dist/types/site_info.js.map +0 -1
- package/dist/types/vehicle.d.ts +0 -23
- package/dist/types/vehicle.js +0 -10
- package/dist/types/vehicle.js.map +0 -1
- package/dist/types/vehicle_data.d.ts +0 -274
- package/dist/types/vehicle_data.js +0 -2
- package/dist/types/vehicle_data.js.map +0 -1
- package/dist/user.d.ts +0 -16
- package/dist/user.js +0 -26
- package/dist/user.js.map +0 -1
- package/dist/vehicle.d.ts +0 -548
- package/dist/vehicle.js +0 -774
- package/dist/vehicle.js.map +0 -1
- package/dist/vehiclesigned.d.ts +0 -13
- package/dist/vehiclesigned.js +0 -19
- package/dist/vehiclesigned.js.map +0 -1
- package/dist/vehiclespecific.d.ts +0 -432
- package/dist/vehiclespecific.js +0 -601
- package/dist/vehiclespecific.js.map +0 -1
- package/src/charging.ts +0 -66
- package/src/commands.ts +0 -1134
- package/src/energy.ts +0 -217
- package/src/energyspecific.ts +0 -116
- package/src/helpers.ts +0 -11
- package/src/index.ts +0 -21
- package/src/partner.ts +0 -37
- package/src/signing/crypto.ts +0 -29
- package/src/signing/errors.ts +0 -50
- package/src/signing/session.ts +0 -132
- package/src/tariff.ts +0 -375
- package/src/teslafleetapi.ts +0 -182
- package/src/teslemetry.ts +0 -54
- package/src/tessie.ts +0 -42
- package/src/types/commands.ts +0 -62
- package/src/types/live_status.ts +0 -27
- package/src/types/products.ts +0 -61
- package/src/types/responses.ts +0 -1
- package/src/types/site_info.ts +0 -159
- package/src/types/vehicle.ts +0 -33
- package/src/types/vehicle_data.ts +0 -286
- package/src/user.ts +0 -35
- package/src/vehicle.ts +0 -886
- package/src/vehiclesigned.ts +0 -20
- package/src/vehiclespecific.ts +0 -818
package/dist/commands.js
DELETED
|
@@ -1,875 +0,0 @@
|
|
|
1
|
-
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
|
|
2
|
-
if (kind === "m") throw new TypeError("Private method is not writable");
|
|
3
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
|
|
4
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
|
|
5
|
-
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
|
|
6
|
-
};
|
|
7
|
-
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) {
|
|
8
|
-
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
|
|
9
|
-
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
|
|
10
|
-
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
|
|
11
|
-
};
|
|
12
|
-
var _Commands_privateKey, _Commands_publicKey;
|
|
13
|
-
import crypto from "crypto";
|
|
14
|
-
import { Domain, MessageFaultE, RoutableMessage, OperationStatusE as MessageOperationStatusE, } from "@teslemetry/tesla-protocol/command/universal_message";
|
|
15
|
-
import { KeyIdentity, SessionInfo, SessionInfoStatus, Tag, SignatureType, } from "@teslemetry/tesla-protocol/command/signatures";
|
|
16
|
-
import { UnsignedMessage, RKEActionE, ClosureMoveRequest, ClosureMoveTypeE, FromVCSECMessage, OperationStatusE as VcsecOperationStatusE, signedMessageInformationEToJSON, } from "@teslemetry/tesla-protocol/command/vcsec";
|
|
17
|
-
import { genericErrorEToJSON } from "@teslemetry/tesla-protocol/command/errors";
|
|
18
|
-
import { Action, VehicleAction, Response, OperationStatusE as ActionOperationStatusE, ChargingStartStopAction, HvacAutoAction, VehicleControlFlashLightsAction, VehicleControlHonkHornAction, VehicleControlCancelSoftwareUpdateAction, VehicleControlScheduleSoftwareUpdateAction, VehicleControlResetPinToDriveAction, VehicleControlResetPinToDriveAdminAction, VehicleControlResetValetPinAction, VehicleControlSetPinToDriveAction, VehicleControlSetSentryModeAction, VehicleControlSetValetModeAction, VehicleControlSunroofOpenCloseAction, VehicleControlTriggerHomelinkAction, VehicleControlWindowAction, EraseUserDataAction, HvacBioweaponModeAction, HvacClimateKeeperAction_ClimateKeeperActionE, HvacSeatCoolerActions, HvacSeatCoolerActions_HvacSeatCoolerAction, HvacSeatCoolerActions_HvacSeatCoolerLevelE, HvacSeatCoolerActions_HvacSeatCoolerPositionE, HvacSeatHeaterActions, HvacSeatHeaterActions_HvacSeatHeaterAction, HvacSetPreconditioningMaxAction, HvacSteeringWheelHeaterAction, HvacTemperatureAdjustmentAction, AutoSeatClimateAction, AutoSeatClimateAction_CarSeat, AutoSeatClimateAction_AutoSeatPositionE, AutoStwHeatAction, StwHeatLevelAction, BoomboxAction, ChargingSetLimitAction, SetChargingAmpsAction, SetCabinOverheatProtectionAction, SetCopTempAction, SetVehicleNameAction, MediaUpdateVolume, NavigationGpsRequest, NavigationRequest, NavigationSuperchargerRequest, DrivingSetSpeedLimitAction, DrivingSpeedLimitAction, DrivingClearSpeedLimitPinAction, DrivingClearSpeedLimitPinAdminAction, ScheduledChargingAction, ScheduledDepartureAction, TakeDrivenoteAction, UiSetUpcomingCalendarEntries, } from "@teslemetry/tesla-protocol/command/car_server";
|
|
19
|
-
import { LatLong, PreconditioningTimes, OffPeakChargingTimes, StwHeatLevel } from "@teslemetry/tesla-protocol/command/common";
|
|
20
|
-
import { VehicleState_GuestMode, ClimateState_CopActivationTemp } from "@teslemetry/tesla-protocol/command/vehicle";
|
|
21
|
-
import { ClimateModes, Seats } from "./types/commands.js";
|
|
22
|
-
import VehicleSpecific from "./vehiclespecific.js";
|
|
23
|
-
import { Session } from "./signing/session.js";
|
|
24
|
-
import { deriveSharedKey, publicKeyFor, uint32BE } from "./signing/crypto.js";
|
|
25
|
-
import { NotOnVehicleWhitelistError, RetryableSignedCommandFaultError, SignedCommandError, createFaultError, } from "./signing/errors.js";
|
|
26
|
-
const VOID = {};
|
|
27
|
-
/** Maximum HMAC-personalized (re)send attempts for one logical command, matching the reference implementation. */
|
|
28
|
-
const MAX_ATTEMPTS = 4;
|
|
29
|
-
const TrunkFields = {
|
|
30
|
-
front: "frontTrunk",
|
|
31
|
-
rear: "rearTrunk",
|
|
32
|
-
};
|
|
33
|
-
/** Node's REST `Seats` values mapped onto the seat-heater oneof field they select. */
|
|
34
|
-
const SeatHeaterFields = {
|
|
35
|
-
[Seats.FRONT_LEFT]: "carSeatFrontLeft",
|
|
36
|
-
[Seats.FRONT_RIGHT]: "carSeatFrontRight",
|
|
37
|
-
[Seats.REAR_LEFT]: "carSeatRearLeft",
|
|
38
|
-
[Seats.REAR_CENTER]: "carSeatRearCenter",
|
|
39
|
-
[Seats.REAR_RIGHT]: "carSeatRearRight",
|
|
40
|
-
[Seats.THIRD_ROW_LEFT]: "carSeatThirdRowLeft",
|
|
41
|
-
[Seats.THIRD_ROW_RIGHT]: "carSeatThirdRowRight",
|
|
42
|
-
};
|
|
43
|
-
const SeatHeaterLevels = [
|
|
44
|
-
"seatHeaterOff",
|
|
45
|
-
"seatHeaterLow",
|
|
46
|
-
"seatHeaterMed",
|
|
47
|
-
"seatHeaterHigh",
|
|
48
|
-
];
|
|
49
|
-
/** Seat cooling and auto-climate only cover the front seats on the wire protocol. */
|
|
50
|
-
const SeatCoolerPositions = {
|
|
51
|
-
[Seats.FRONT_LEFT]: HvacSeatCoolerActions_HvacSeatCoolerPositionE.HvacSeatCoolerPosition_FrontLeft,
|
|
52
|
-
[Seats.FRONT_RIGHT]: HvacSeatCoolerActions_HvacSeatCoolerPositionE.HvacSeatCoolerPosition_FrontRight,
|
|
53
|
-
};
|
|
54
|
-
const SeatCoolerLevels = [
|
|
55
|
-
HvacSeatCoolerActions_HvacSeatCoolerLevelE.HvacSeatCoolerLevel_Off,
|
|
56
|
-
HvacSeatCoolerActions_HvacSeatCoolerLevelE.HvacSeatCoolerLevel_Low,
|
|
57
|
-
HvacSeatCoolerActions_HvacSeatCoolerLevelE.HvacSeatCoolerLevel_Med,
|
|
58
|
-
HvacSeatCoolerActions_HvacSeatCoolerLevelE.HvacSeatCoolerLevel_High,
|
|
59
|
-
];
|
|
60
|
-
const AutoSeatPositions = {
|
|
61
|
-
[Seats.FRONT_LEFT]: AutoSeatClimateAction_AutoSeatPositionE.AutoSeatPosition_FrontLeft,
|
|
62
|
-
[Seats.FRONT_RIGHT]: AutoSeatClimateAction_AutoSeatPositionE.AutoSeatPosition_FrontRight,
|
|
63
|
-
};
|
|
64
|
-
const StwHeatLevels = [StwHeatLevel.StwHeatLevel_Off, StwHeatLevel.StwHeatLevel_Low, StwHeatLevel.StwHeatLevel_High];
|
|
65
|
-
const ClimateKeeperActions = {
|
|
66
|
-
[ClimateModes.Off]: HvacClimateKeeperAction_ClimateKeeperActionE.ClimateKeeperAction_Off,
|
|
67
|
-
[ClimateModes.Keep]: HvacClimateKeeperAction_ClimateKeeperActionE.ClimateKeeperAction_On,
|
|
68
|
-
[ClimateModes.Dog]: HvacClimateKeeperAction_ClimateKeeperActionE.ClimateKeeperAction_Dog,
|
|
69
|
-
[ClimateModes.Camp]: HvacClimateKeeperAction_ClimateKeeperActionE.ClimateKeeperAction_Camp,
|
|
70
|
-
};
|
|
71
|
-
/** `set_cop_temp` accepts either the enum index or the Celsius/Fahrenheit value it represents. */
|
|
72
|
-
const CopActivationTemps = {
|
|
73
|
-
0: ClimateState_CopActivationTemp.CopActivationTempLow,
|
|
74
|
-
30: ClimateState_CopActivationTemp.CopActivationTempLow,
|
|
75
|
-
90: ClimateState_CopActivationTemp.CopActivationTempLow,
|
|
76
|
-
1: ClimateState_CopActivationTemp.CopActivationTempMedium,
|
|
77
|
-
35: ClimateState_CopActivationTemp.CopActivationTempMedium,
|
|
78
|
-
95: ClimateState_CopActivationTemp.CopActivationTempMedium,
|
|
79
|
-
2: ClimateState_CopActivationTemp.CopActivationTempHigh,
|
|
80
|
-
40: ClimateState_CopActivationTemp.CopActivationTempHigh,
|
|
81
|
-
100: ClimateState_CopActivationTemp.CopActivationTempHigh,
|
|
82
|
-
};
|
|
83
|
-
function sleep(ms) {
|
|
84
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
85
|
-
}
|
|
86
|
-
function ok(reason = "") {
|
|
87
|
-
return { response: { result: true, reason } };
|
|
88
|
-
}
|
|
89
|
-
function fail(reason) {
|
|
90
|
-
return { response: { result: false, reason } };
|
|
91
|
-
}
|
|
92
|
-
/**
|
|
93
|
-
* Transport-agnostic signed-command builder for the Tesla Vehicle Command
|
|
94
|
-
* Protocol: mirrors `python-tesla-fleet-api`'s `Commands` ABC. Every method
|
|
95
|
-
* here builds a `RoutableMessage`, signs it (HMAC-personalized), and
|
|
96
|
-
* dispatches it through the single abstract seam `_send`. A concrete
|
|
97
|
-
* subclass fills that seam for one transport - the cloud `/signed_command`
|
|
98
|
-
* HTTP endpoint (`VehicleSigned`) today, a BLE GATT link in a future story.
|
|
99
|
-
*
|
|
100
|
-
* AES-GCM personalized signing (the BLE-only auth mode) is intentionally out
|
|
101
|
-
* of scope here; see AGENTS.md.
|
|
102
|
-
*/
|
|
103
|
-
class Commands extends VehicleSpecific {
|
|
104
|
-
constructor(parent, vin, privateKey, publicKey) {
|
|
105
|
-
super(parent, vin);
|
|
106
|
-
// Native private fields (not `protected`/TS-only `private`): the raw key
|
|
107
|
-
// must not be reachable off the instance, e.g. via a naive
|
|
108
|
-
// JSON.stringify/structured log, not just inaccessible to outside code
|
|
109
|
-
// at compile time.
|
|
110
|
-
_Commands_privateKey.set(this, void 0);
|
|
111
|
-
_Commands_publicKey.set(this, void 0);
|
|
112
|
-
/** Delay between WAIT-retries; overridable so tests don't have to wait for real timers. */
|
|
113
|
-
this.retryDelayMs = 2000;
|
|
114
|
-
if (vin.length !== 17) {
|
|
115
|
-
throw new Error(`Signed commands require a 17-character VIN, got ${vin.length} characters.`);
|
|
116
|
-
}
|
|
117
|
-
const resolvedPrivateKey = privateKey ?? parent.private_key;
|
|
118
|
-
if (!resolvedPrivateKey) {
|
|
119
|
-
throw new Error("No private key provided for signed commands.");
|
|
120
|
-
}
|
|
121
|
-
__classPrivateFieldSet(this, _Commands_privateKey, resolvedPrivateKey, "f");
|
|
122
|
-
__classPrivateFieldSet(this, _Commands_publicKey, publicKey ?? publicKeyFor(__classPrivateFieldGet(this, _Commands_privateKey, "f")), "f");
|
|
123
|
-
this.fromDestination = crypto.randomBytes(16);
|
|
124
|
-
const deriveKey = (vehiclePublicKey) => deriveSharedKey(__classPrivateFieldGet(this, _Commands_privateKey, "f"), vehiclePublicKey);
|
|
125
|
-
this.sessions = {
|
|
126
|
-
[Domain.DOMAIN_VEHICLE_SECURITY]: new Session(Domain.DOMAIN_VEHICLE_SECURITY, deriveKey),
|
|
127
|
-
[Domain.DOMAIN_INFOTAINMENT]: new Session(Domain.DOMAIN_INFOTAINMENT, deriveKey),
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
sessionFor(domain) {
|
|
131
|
-
const session = this.sessions[domain];
|
|
132
|
-
if (!session) {
|
|
133
|
-
throw new Error(`No signed-command session configured for domain ${domain}.`);
|
|
134
|
-
}
|
|
135
|
-
return session;
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Absorb session info piggy-backed on any signed-command reply and raise
|
|
139
|
-
* on a whitelist rejection or a terminal message fault. Every concrete
|
|
140
|
-
* `_send` must call this on the reply - passing the `uuid` of the request
|
|
141
|
-
* it just sent - before returning it.
|
|
142
|
-
*
|
|
143
|
-
* A `SessionInfo` is untrusted wire data until its `session_info_tag` is
|
|
144
|
-
* verified: the tag is an HMAC over the exact bytes received, keyed by a
|
|
145
|
-
* key derived from the *candidate* vehicle public key carried inside that
|
|
146
|
-
* same SessionInfo, and bound to this request's `uuid` as a challenge (so
|
|
147
|
-
* a captured older reply can't be replayed against a newer request). Only
|
|
148
|
-
* once that tag checks out do we act on anything the message claims -
|
|
149
|
-
* including its own whitelist-status field - and even then `Session.commit`
|
|
150
|
-
* still refuses a clock time that regresses within the same epoch.
|
|
151
|
-
*/
|
|
152
|
-
validateAndUpdateSession(resp, requestUuid) {
|
|
153
|
-
if (resp.sessionInfo && resp.sessionInfo.length > 0) {
|
|
154
|
-
const domain = resp.fromDestination?.domain;
|
|
155
|
-
const session = domain !== undefined ? this.sessions[domain] : undefined;
|
|
156
|
-
if (!session) {
|
|
157
|
-
throw new SignedCommandError("Session info reply is missing a recognized source domain.");
|
|
158
|
-
}
|
|
159
|
-
// VCSEC typically leaves request_uuid empty on real vehicles
|
|
160
|
-
// (memory constraints), so its absence must not be treated as a
|
|
161
|
-
// rejection - the tag below, which binds the *sent* requestUuid
|
|
162
|
-
// as TAG_CHALLENGE, is the actual authentication. Only cross-check
|
|
163
|
-
// the echo when the vehicle chose to populate it.
|
|
164
|
-
if (resp.requestUuid && resp.requestUuid.length > 0 && !requestUuid.equals(Buffer.from(resp.requestUuid))) {
|
|
165
|
-
throw new SignedCommandError("Session info reply does not match an outstanding request; discarded.");
|
|
166
|
-
}
|
|
167
|
-
const info = SessionInfo.decode(resp.sessionInfo);
|
|
168
|
-
const keys = session.keysFor(Buffer.from(info.publicKey));
|
|
169
|
-
const tag = resp.signatureData?.sessionInfoTag?.tag;
|
|
170
|
-
if (!tag || tag.length === 0) {
|
|
171
|
-
throw new SignedCommandError("Session info reply is missing its authentication tag; discarded.");
|
|
172
|
-
}
|
|
173
|
-
const metadata = Buffer.concat([
|
|
174
|
-
Buffer.from([Tag.TAG_SIGNATURE_TYPE, 1, SignatureType.SIGNATURE_TYPE_HMAC]),
|
|
175
|
-
Buffer.from([Tag.TAG_PERSONALIZATION, 17]),
|
|
176
|
-
Buffer.from(this.vin, "ascii"),
|
|
177
|
-
Buffer.from([Tag.TAG_CHALLENGE, requestUuid.length]),
|
|
178
|
-
requestUuid,
|
|
179
|
-
Buffer.from([Tag.TAG_END]),
|
|
180
|
-
]);
|
|
181
|
-
const expectedTag = crypto
|
|
182
|
-
.createHmac("sha256", keys.sessionInfoKey)
|
|
183
|
-
.update(Buffer.concat([metadata, Buffer.from(resp.sessionInfo)]))
|
|
184
|
-
.digest();
|
|
185
|
-
const receivedTag = Buffer.from(tag);
|
|
186
|
-
if (expectedTag.length !== receivedTag.length || !crypto.timingSafeEqual(expectedTag, receivedTag)) {
|
|
187
|
-
throw new SignedCommandError("Session info reply failed authentication (invalid tag); discarded.");
|
|
188
|
-
}
|
|
189
|
-
// Only now that the reply is authenticated do we act on its contents.
|
|
190
|
-
if (info.status === SessionInfoStatus.SESSION_INFO_STATUS_KEY_NOT_ON_WHITELIST) {
|
|
191
|
-
throw new NotOnVehicleWhitelistError();
|
|
192
|
-
}
|
|
193
|
-
if (!session.commit(info, keys)) {
|
|
194
|
-
throw new SignedCommandError("Session info reply is stale (clock regressed within the same epoch); discarded.");
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
const fault = resp.signedMessageStatus?.signedMessageFault;
|
|
198
|
-
if (fault !== undefined && fault !== MessageFaultE.MESSAGEFAULT_ERROR_NONE) {
|
|
199
|
-
throw createFaultError(fault);
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
async handshake(domain) {
|
|
203
|
-
const msg = RoutableMessage.create({
|
|
204
|
-
toDestination: { domain },
|
|
205
|
-
fromDestination: { routingAddress: this.fromDestination },
|
|
206
|
-
sessionInfoRequest: { publicKey: __classPrivateFieldGet(this, _Commands_publicKey, "f") },
|
|
207
|
-
uuid: crypto.randomBytes(16),
|
|
208
|
-
});
|
|
209
|
-
await this._send(msg, "session_info");
|
|
210
|
-
}
|
|
211
|
-
buildHmacMessage(session, command) {
|
|
212
|
-
const personalized = session.hmacPersonalized();
|
|
213
|
-
if (!session.hmacKey) {
|
|
214
|
-
throw new Error("Session HMAC key is missing.");
|
|
215
|
-
}
|
|
216
|
-
const metadata = Buffer.concat([
|
|
217
|
-
Buffer.from([Tag.TAG_SIGNATURE_TYPE, 1, SignatureType.SIGNATURE_TYPE_HMAC_PERSONALIZED]),
|
|
218
|
-
Buffer.from([Tag.TAG_DOMAIN, 1, session.domain]),
|
|
219
|
-
Buffer.from([Tag.TAG_PERSONALIZATION, 17]),
|
|
220
|
-
Buffer.from(this.vin, "ascii"),
|
|
221
|
-
Buffer.from([Tag.TAG_EPOCH, personalized.epoch.length]),
|
|
222
|
-
Buffer.from(personalized.epoch),
|
|
223
|
-
Buffer.from([Tag.TAG_EXPIRES_AT, 4]),
|
|
224
|
-
uint32BE(personalized.expiresAt),
|
|
225
|
-
Buffer.from([Tag.TAG_COUNTER, 4]),
|
|
226
|
-
uint32BE(personalized.counter),
|
|
227
|
-
Buffer.from([Tag.TAG_END]),
|
|
228
|
-
]);
|
|
229
|
-
const tag = crypto.createHmac("sha256", session.hmacKey).update(Buffer.concat([metadata, command])).digest();
|
|
230
|
-
return RoutableMessage.create({
|
|
231
|
-
toDestination: { domain: session.domain },
|
|
232
|
-
fromDestination: { routingAddress: this.fromDestination },
|
|
233
|
-
protobufMessageAsBytes: command,
|
|
234
|
-
uuid: crypto.randomBytes(16),
|
|
235
|
-
signatureData: {
|
|
236
|
-
signerIdentity: KeyIdentity.create({ publicKey: __classPrivateFieldGet(this, _Commands_publicKey, "f") }),
|
|
237
|
-
HMACPersonalizedData: { ...personalized, tag },
|
|
238
|
-
},
|
|
239
|
-
});
|
|
240
|
-
}
|
|
241
|
-
/**
|
|
242
|
-
* Build, sign, dispatch (with WAIT/epoch-fault retry), and interpret one
|
|
243
|
-
* domain command.
|
|
244
|
-
*
|
|
245
|
-
* VCSEC requires messages to arrive in strict counter order and warns
|
|
246
|
-
* clients to avoid simultaneous requests to it at all (unlike
|
|
247
|
-
* Infotainment, which tolerates a sliding window) - so for
|
|
248
|
-
* `DOMAIN_VEHICLE_SECURITY` the *entire* dispatch (handshake, build,
|
|
249
|
-
* send, and any retry) runs under the domain's lock, guaranteeing at
|
|
250
|
-
* most one VCSEC message is ever in flight. Infotainment keeps the
|
|
251
|
-
* narrower build-only lock, serializing only counter assignment.
|
|
252
|
-
*/
|
|
253
|
-
async dispatch(domain, command, expectsData) {
|
|
254
|
-
const session = this.sessionFor(domain);
|
|
255
|
-
const serializeWholeDispatch = domain === Domain.DOMAIN_VEHICLE_SECURITY;
|
|
256
|
-
const run = async () => {
|
|
257
|
-
if (!session.ready) {
|
|
258
|
-
await this.handshake(domain);
|
|
259
|
-
}
|
|
260
|
-
for (let attempt = 0; attempt < MAX_ATTEMPTS; attempt++) {
|
|
261
|
-
const msg = serializeWholeDispatch
|
|
262
|
-
? this.buildHmacMessage(session, command)
|
|
263
|
-
: await session.withLock(() => this.buildHmacMessage(session, command));
|
|
264
|
-
let resp;
|
|
265
|
-
try {
|
|
266
|
-
resp = await this._send(msg, "protobuf_message_as_bytes", expectsData);
|
|
267
|
-
}
|
|
268
|
-
catch (error) {
|
|
269
|
-
if (error instanceof RetryableSignedCommandFaultError && attempt < MAX_ATTEMPTS - 1) {
|
|
270
|
-
continue;
|
|
271
|
-
}
|
|
272
|
-
throw error;
|
|
273
|
-
}
|
|
274
|
-
if (resp.signedMessageStatus?.operationStatus === MessageOperationStatusE.OPERATIONSTATUS_WAIT) {
|
|
275
|
-
if (attempt >= MAX_ATTEMPTS - 1) {
|
|
276
|
-
return fail("Too many retries");
|
|
277
|
-
}
|
|
278
|
-
await sleep(this.retryDelayMs);
|
|
279
|
-
continue;
|
|
280
|
-
}
|
|
281
|
-
const result = this.interpretResponse(resp);
|
|
282
|
-
if (result === "wait") {
|
|
283
|
-
if (attempt >= MAX_ATTEMPTS - 1) {
|
|
284
|
-
return fail("Too many retries");
|
|
285
|
-
}
|
|
286
|
-
await sleep(this.retryDelayMs);
|
|
287
|
-
continue;
|
|
288
|
-
}
|
|
289
|
-
return result;
|
|
290
|
-
}
|
|
291
|
-
return fail("Too many retries");
|
|
292
|
-
};
|
|
293
|
-
return serializeWholeDispatch ? session.withLock(run) : run();
|
|
294
|
-
}
|
|
295
|
-
interpretResponse(resp) {
|
|
296
|
-
if (!resp.protobufMessageAsBytes || resp.protobufMessageAsBytes.length === 0) {
|
|
297
|
-
return ok();
|
|
298
|
-
}
|
|
299
|
-
const domain = resp.fromDestination?.domain;
|
|
300
|
-
if (domain === Domain.DOMAIN_VEHICLE_SECURITY) {
|
|
301
|
-
return this.interpretVcsecResponse(resp.protobufMessageAsBytes);
|
|
302
|
-
}
|
|
303
|
-
if (domain === Domain.DOMAIN_INFOTAINMENT) {
|
|
304
|
-
return this.interpretInfotainmentResponse(resp.protobufMessageAsBytes);
|
|
305
|
-
}
|
|
306
|
-
return ok();
|
|
307
|
-
}
|
|
308
|
-
interpretVcsecResponse(bytes) {
|
|
309
|
-
const vcsec = FromVCSECMessage.decode(bytes);
|
|
310
|
-
if (vcsec.nominalError) {
|
|
311
|
-
return fail(genericErrorEToJSON(vcsec.nominalError.genericError));
|
|
312
|
-
}
|
|
313
|
-
if (vcsec.vehicleStatus) {
|
|
314
|
-
// Every current VCSEC command is an actuation, so a populated
|
|
315
|
-
// vehicleStatus here is always the ack, never a requested read.
|
|
316
|
-
return ok();
|
|
317
|
-
}
|
|
318
|
-
if (vcsec.commandStatus) {
|
|
319
|
-
if (vcsec.commandStatus.operationStatus === VcsecOperationStatusE.OPERATIONSTATUS_OK) {
|
|
320
|
-
return ok();
|
|
321
|
-
}
|
|
322
|
-
if (vcsec.commandStatus.operationStatus === VcsecOperationStatusE.OPERATIONSTATUS_WAIT) {
|
|
323
|
-
return "wait";
|
|
324
|
-
}
|
|
325
|
-
if (vcsec.commandStatus.operationStatus === VcsecOperationStatusE.OPERATIONSTATUS_ERROR) {
|
|
326
|
-
const information = vcsec.commandStatus.signedMessageStatus?.signedMessageInformation;
|
|
327
|
-
if (information) {
|
|
328
|
-
throw new SignedCommandError(`Vehicle security rejected signed command: ${signedMessageInformationEToJSON(information)}`);
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
}
|
|
332
|
-
return ok();
|
|
333
|
-
}
|
|
334
|
-
interpretInfotainmentResponse(bytes) {
|
|
335
|
-
const response = Response.decode(bytes);
|
|
336
|
-
if (response.ping) {
|
|
337
|
-
return ok(String(response.ping.localTimestamp ?? ""));
|
|
338
|
-
}
|
|
339
|
-
if (response.actionStatus) {
|
|
340
|
-
return {
|
|
341
|
-
response: {
|
|
342
|
-
result: response.actionStatus.result === ActionOperationStatusE.OPERATIONSTATUS_OK,
|
|
343
|
-
reason: response.actionStatus.resultReason?.plainText ?? "",
|
|
344
|
-
},
|
|
345
|
-
};
|
|
346
|
-
}
|
|
347
|
-
return ok();
|
|
348
|
-
}
|
|
349
|
-
async sendVehicleSecurity(command) {
|
|
350
|
-
return this.dispatch(Domain.DOMAIN_VEHICLE_SECURITY, Buffer.from(UnsignedMessage.encode(command).finish()), false);
|
|
351
|
-
}
|
|
352
|
-
async sendInfotainment(action) {
|
|
353
|
-
return this.dispatch(Domain.DOMAIN_INFOTAINMENT, Buffer.from(Action.encode(action).finish()), true);
|
|
354
|
-
}
|
|
355
|
-
vehicleAction(action) {
|
|
356
|
-
return this.sendInfotainment(Action.create({ vehicleAction: action }));
|
|
357
|
-
}
|
|
358
|
-
resolveSeat(seat_position) {
|
|
359
|
-
return typeof seat_position === "string" ? Seats[seat_position] : seat_position;
|
|
360
|
-
}
|
|
361
|
-
// Vehicle Commands
|
|
362
|
-
/**
|
|
363
|
-
* Controls the front (which_trunk: "front") or rear (which_trunk: "rear") trunk.
|
|
364
|
-
* @param which_trunk "front" or "rear"
|
|
365
|
-
*/
|
|
366
|
-
async actuate_truck(which_trunk) {
|
|
367
|
-
const field = TrunkFields[which_trunk];
|
|
368
|
-
if (!field) {
|
|
369
|
-
throw new Error(`Invalid trunk: ${which_trunk}`);
|
|
370
|
-
}
|
|
371
|
-
const closureMoveRequest = {};
|
|
372
|
-
closureMoveRequest[field] = ClosureMoveTypeE.CLOSURE_MOVE_TYPE_MOVE;
|
|
373
|
-
return this.sendVehicleSecurity(UnsignedMessage.create({ closureMoveRequest: ClosureMoveRequest.create(closureMoveRequest) }));
|
|
374
|
-
}
|
|
375
|
-
/**
|
|
376
|
-
* Adjusts vehicle media playback volume.
|
|
377
|
-
* @param volume A floating point number from 0.0 to 11.0.
|
|
378
|
-
*/
|
|
379
|
-
async adjust_volume(volume) {
|
|
380
|
-
return this.vehicleAction(VehicleAction.create({ mediaUpdateVolume: MediaUpdateVolume.create({ volumeAbsoluteFloat: volume }) }));
|
|
381
|
-
}
|
|
382
|
-
/** Starts climate preconditioning. */
|
|
383
|
-
async auto_conditioning_start() {
|
|
384
|
-
return this.vehicleAction(VehicleAction.create({ hvacAutoAction: HvacAutoAction.create({ powerOn: true }) }));
|
|
385
|
-
}
|
|
386
|
-
/** Stops climate preconditioning. */
|
|
387
|
-
async auto_conditioning_stop() {
|
|
388
|
-
return this.vehicleAction(VehicleAction.create({ hvacAutoAction: HvacAutoAction.create({ powerOn: false }) }));
|
|
389
|
-
}
|
|
390
|
-
/** Cancels the countdown to install the vehicle software update. */
|
|
391
|
-
async cancel_software_update() {
|
|
392
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlCancelSoftwareUpdateAction: VehicleControlCancelSoftwareUpdateAction.create({}) }));
|
|
393
|
-
}
|
|
394
|
-
/** Charges in max range mode -- we recommend limiting the use of this mode to long trips. */
|
|
395
|
-
async charge_max_range() {
|
|
396
|
-
return this.vehicleAction(VehicleAction.create({ chargingStartStopAction: ChargingStartStopAction.create({ startMaxRange: VOID }) }));
|
|
397
|
-
}
|
|
398
|
-
/** Closes the charge port door. */
|
|
399
|
-
async charge_port_door_close() {
|
|
400
|
-
return this.sendVehicleSecurity(UnsignedMessage.create({
|
|
401
|
-
closureMoveRequest: ClosureMoveRequest.create({ chargePort: ClosureMoveTypeE.CLOSURE_MOVE_TYPE_CLOSE }),
|
|
402
|
-
}));
|
|
403
|
-
}
|
|
404
|
-
/** Opens the charge port door. */
|
|
405
|
-
async charge_port_door_open() {
|
|
406
|
-
return this.sendVehicleSecurity(UnsignedMessage.create({
|
|
407
|
-
closureMoveRequest: ClosureMoveRequest.create({ chargePort: ClosureMoveTypeE.CLOSURE_MOVE_TYPE_OPEN }),
|
|
408
|
-
}));
|
|
409
|
-
}
|
|
410
|
-
/** Charges in Standard mode. */
|
|
411
|
-
async charge_standard() {
|
|
412
|
-
return this.vehicleAction(VehicleAction.create({ chargingStartStopAction: ChargingStartStopAction.create({ startStandard: VOID }) }));
|
|
413
|
-
}
|
|
414
|
-
/** Starts charging the vehicle. */
|
|
415
|
-
async charge_start() {
|
|
416
|
-
return this.vehicleAction(VehicleAction.create({ chargingStartStopAction: ChargingStartStopAction.create({ start: VOID }) }));
|
|
417
|
-
}
|
|
418
|
-
/** Stops charging the vehicle. */
|
|
419
|
-
async charge_stop() {
|
|
420
|
-
return this.vehicleAction(VehicleAction.create({ chargingStartStopAction: ChargingStartStopAction.create({ stop: VOID }) }));
|
|
421
|
-
}
|
|
422
|
-
/**
|
|
423
|
-
* 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.
|
|
424
|
-
*/
|
|
425
|
-
async clear_pin_to_drive_admin() {
|
|
426
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlResetPinToDriveAdminAction: VehicleControlResetPinToDriveAdminAction.create({}) }));
|
|
427
|
-
}
|
|
428
|
-
/** Locks the vehicle. */
|
|
429
|
-
async door_lock() {
|
|
430
|
-
return this.sendVehicleSecurity(UnsignedMessage.create({ RKEAction: RKEActionE.RKE_ACTION_LOCK }));
|
|
431
|
-
}
|
|
432
|
-
/** Unlocks the vehicle. */
|
|
433
|
-
async door_unlock() {
|
|
434
|
-
return this.sendVehicleSecurity(UnsignedMessage.create({ RKEAction: RKEActionE.RKE_ACTION_UNLOCK }));
|
|
435
|
-
}
|
|
436
|
-
/** Erases user's data from the user interface. Requires the vehicle to be in park. */
|
|
437
|
-
async erase_user_data() {
|
|
438
|
-
return this.vehicleAction(VehicleAction.create({ eraseUserDataAction: EraseUserDataAction.create({}) }));
|
|
439
|
-
}
|
|
440
|
-
/** Briefly flashes the vehicle headlights. Requires the vehicle to be in park. */
|
|
441
|
-
async flash_lights() {
|
|
442
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlFlashLightsAction: VehicleControlFlashLightsAction.create({}) }));
|
|
443
|
-
}
|
|
444
|
-
/**
|
|
445
|
-
* Restricts certain vehicle UI functionality from guest users
|
|
446
|
-
* @param enable `true` or `false`
|
|
447
|
-
*/
|
|
448
|
-
async guest_mode(enable) {
|
|
449
|
-
return this.vehicleAction(VehicleAction.create({ guestModeAction: VehicleState_GuestMode.create({ GuestModeActive: enable }) }));
|
|
450
|
-
}
|
|
451
|
-
/** Honks the vehicle horn. Requires the vehicle to be in park. */
|
|
452
|
-
async honk_horn() {
|
|
453
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlHonkHornAction: VehicleControlHonkHornAction.create({}) }));
|
|
454
|
-
}
|
|
455
|
-
/** Advances media player to next favorite track. */
|
|
456
|
-
async media_next_fav() {
|
|
457
|
-
return this.vehicleAction(VehicleAction.create({ mediaNextFavorite: {} }));
|
|
458
|
-
}
|
|
459
|
-
/** Advances media player to next track. */
|
|
460
|
-
async media_next_track() {
|
|
461
|
-
return this.vehicleAction(VehicleAction.create({ mediaNextTrack: {} }));
|
|
462
|
-
}
|
|
463
|
-
/** Advances media player to previous favorite track. */
|
|
464
|
-
async media_prev_fav() {
|
|
465
|
-
return this.vehicleAction(VehicleAction.create({ mediaPreviousFavorite: {} }));
|
|
466
|
-
}
|
|
467
|
-
/** Advances media player to previous track. */
|
|
468
|
-
async media_prev_track() {
|
|
469
|
-
return this.vehicleAction(VehicleAction.create({ mediaPreviousTrack: {} }));
|
|
470
|
-
}
|
|
471
|
-
/** Toggles current play/pause state. */
|
|
472
|
-
async media_toggle_playback() {
|
|
473
|
-
return this.vehicleAction(VehicleAction.create({ mediaPlayAction: {} }));
|
|
474
|
-
}
|
|
475
|
-
/** Turns the volume down by one. */
|
|
476
|
-
async media_volume_down() {
|
|
477
|
-
return this.vehicleAction(VehicleAction.create({ mediaUpdateVolume: MediaUpdateVolume.create({ volumeDelta: -1 }) }));
|
|
478
|
-
}
|
|
479
|
-
/**
|
|
480
|
-
* Start navigation to given coordinates. Order can be used to specify order of multiple stops.
|
|
481
|
-
* @param lat Latitude
|
|
482
|
-
* @param lon Longitude
|
|
483
|
-
* @param order Order of multiple stops
|
|
484
|
-
*/
|
|
485
|
-
async navigation_gps_request(lat, lon, order = 0) {
|
|
486
|
-
return this.vehicleAction(VehicleAction.create({ navigationGpsRequest: NavigationGpsRequest.create({ lat, lon, order }) }));
|
|
487
|
-
}
|
|
488
|
-
/**
|
|
489
|
-
* Sends a location to the in-vehicle navigation system.
|
|
490
|
-
*
|
|
491
|
-
* `locale` and `type` are REST-only fields with no equivalent in the
|
|
492
|
-
* signed-command protocol (which only carries a destination string and a
|
|
493
|
-
* multi-stop order), so they are accepted for cross-transport signature
|
|
494
|
-
* parity but not sent.
|
|
495
|
-
* @param value Destination text
|
|
496
|
-
*/
|
|
497
|
-
async navigation_request(value, _locale, _type) {
|
|
498
|
-
return this.vehicleAction(VehicleAction.create({ navigationRequest: NavigationRequest.create({ destination: value }) }));
|
|
499
|
-
}
|
|
500
|
-
/**
|
|
501
|
-
* Start navigation to a supercharger.
|
|
502
|
-
*
|
|
503
|
-
* The signed-command protobuf has a single `order` field carrying the
|
|
504
|
-
* supercharger identifier; a caller-supplied multi-stop `order` has no
|
|
505
|
-
* representable slot and is rejected rather than silently dropped.
|
|
506
|
-
* @param id Supercharger ID
|
|
507
|
-
* @param order Order of multiple stops - not representable in a signed command
|
|
508
|
-
*/
|
|
509
|
-
async navigation_sc_request(id, order) {
|
|
510
|
-
if (order !== undefined) {
|
|
511
|
-
throw new Error("navigation_sc_request: multi-stop order is not representable in a signed command.");
|
|
512
|
-
}
|
|
513
|
-
return this.vehicleAction(VehicleAction.create({ navigationSuperchargerRequest: NavigationSuperchargerRequest.create({ order: id }) }));
|
|
514
|
-
}
|
|
515
|
-
/**
|
|
516
|
-
* Sets automatic seat heating and cooling. Only the front seats support this action.
|
|
517
|
-
* @param auto_seat_position Seat position
|
|
518
|
-
* @param auto_climate_on `true` or `false`
|
|
519
|
-
*/
|
|
520
|
-
async remote_auto_seat_climate_request(auto_seat_position, auto_climate_on) {
|
|
521
|
-
const position = AutoSeatPositions[this.resolveSeat(auto_seat_position)];
|
|
522
|
-
if (position === undefined) {
|
|
523
|
-
throw new Error(`Invalid seat position for auto seat climate: ${auto_seat_position}`);
|
|
524
|
-
}
|
|
525
|
-
return this.vehicleAction(VehicleAction.create({
|
|
526
|
-
autoSeatClimateAction: AutoSeatClimateAction.create({
|
|
527
|
-
carseat: [AutoSeatClimateAction_CarSeat.create({ on: auto_climate_on, seatPosition: position })],
|
|
528
|
-
}),
|
|
529
|
-
}));
|
|
530
|
-
}
|
|
531
|
-
/**
|
|
532
|
-
* Sets automatic steering wheel heating on/off.
|
|
533
|
-
* @param on `true` or `false`
|
|
534
|
-
*/
|
|
535
|
-
async remote_auto_steering_wheel_heat_climate_request(on) {
|
|
536
|
-
return this.vehicleAction(VehicleAction.create({ autoStwHeatAction: AutoStwHeatAction.create({ on }) }));
|
|
537
|
-
}
|
|
538
|
-
/**
|
|
539
|
-
* Plays a sound through the vehicle external speaker.
|
|
540
|
-
* @param sound Fart is `0`, Locate ping is `2000`
|
|
541
|
-
*/
|
|
542
|
-
async remote_boombox(sound = 0) {
|
|
543
|
-
return this.vehicleAction(VehicleAction.create({ boomboxAction: BoomboxAction.create({ sound }) }));
|
|
544
|
-
}
|
|
545
|
-
/**
|
|
546
|
-
* Sets seat cooling. Only the front seats support this action.
|
|
547
|
-
* @param seat_position Seat position
|
|
548
|
-
* @param seat_cooler_level Cooling level
|
|
549
|
-
*/
|
|
550
|
-
async remote_seat_cooler_request(seat_position, seat_cooler_level) {
|
|
551
|
-
const position = SeatCoolerPositions[this.resolveSeat(seat_position)];
|
|
552
|
-
if (position === undefined) {
|
|
553
|
-
throw new Error(`Invalid seat position for seat cooling: ${seat_position}`);
|
|
554
|
-
}
|
|
555
|
-
const level = SeatCoolerLevels[seat_cooler_level];
|
|
556
|
-
if (level === undefined) {
|
|
557
|
-
throw new Error(`Invalid seat cooler level: ${seat_cooler_level}`);
|
|
558
|
-
}
|
|
559
|
-
return this.vehicleAction(VehicleAction.create({
|
|
560
|
-
hvacSeatCoolerActions: HvacSeatCoolerActions.create({
|
|
561
|
-
hvacSeatCoolerAction: [
|
|
562
|
-
HvacSeatCoolerActions_HvacSeatCoolerAction.create({ seatCoolerLevel: level, seatPosition: position }),
|
|
563
|
-
],
|
|
564
|
-
}),
|
|
565
|
-
}));
|
|
566
|
-
}
|
|
567
|
-
/**
|
|
568
|
-
* Sets seat heating.
|
|
569
|
-
* @param seat_position Seat position
|
|
570
|
-
* @param seat_heater_level Heating level
|
|
571
|
-
*/
|
|
572
|
-
async remote_seat_heater_request(seat_position, seat_heater_level) {
|
|
573
|
-
const field = SeatHeaterFields[this.resolveSeat(seat_position)];
|
|
574
|
-
if (!field) {
|
|
575
|
-
throw new Error(`Invalid seat position: ${seat_position}`);
|
|
576
|
-
}
|
|
577
|
-
const levelField = SeatHeaterLevels[seat_heater_level];
|
|
578
|
-
if (!levelField) {
|
|
579
|
-
throw new Error(`Invalid seat heater level: ${seat_heater_level}`);
|
|
580
|
-
}
|
|
581
|
-
const heaterAction = {};
|
|
582
|
-
heaterAction[field] = VOID;
|
|
583
|
-
heaterAction[levelField] = VOID;
|
|
584
|
-
return this.vehicleAction(VehicleAction.create({
|
|
585
|
-
hvacSeatHeaterActions: HvacSeatHeaterActions.create({
|
|
586
|
-
hvacSeatHeaterAction: [HvacSeatHeaterActions_HvacSeatHeaterAction.create(heaterAction)],
|
|
587
|
-
}),
|
|
588
|
-
}));
|
|
589
|
-
}
|
|
590
|
-
/** Starts the vehicle remotely. Requires keyless driving to be enabled. */
|
|
591
|
-
async remote_start_drive() {
|
|
592
|
-
return this.sendVehicleSecurity(UnsignedMessage.create({ RKEAction: RKEActionE.RKE_ACTION_REMOTE_DRIVE }));
|
|
593
|
-
}
|
|
594
|
-
/**
|
|
595
|
-
* Sets steering wheel heat level.
|
|
596
|
-
* @param level Heating level (0=Off, 1=Low, 2=High)
|
|
597
|
-
*/
|
|
598
|
-
async remote_steering_wheel_heat_level_request(level) {
|
|
599
|
-
const stwLevel = StwHeatLevels[level];
|
|
600
|
-
if (stwLevel === undefined) {
|
|
601
|
-
throw new Error(`Invalid steering wheel heat level: ${level}`);
|
|
602
|
-
}
|
|
603
|
-
return this.vehicleAction(VehicleAction.create({ stwHeatLevelAction: StwHeatLevelAction.create({ stwHeatLevel: stwLevel }) }));
|
|
604
|
-
}
|
|
605
|
-
/**
|
|
606
|
-
* Sets steering wheel heating on/off. For vehicles that do not support auto steering wheel heat.
|
|
607
|
-
* @param on `true` or `false`
|
|
608
|
-
*/
|
|
609
|
-
async remote_steering_wheel_heater_request(on) {
|
|
610
|
-
return this.vehicleAction(VehicleAction.create({ hvacSteeringWheelHeaterAction: HvacSteeringWheelHeaterAction.create({ powerOn: on }) }));
|
|
611
|
-
}
|
|
612
|
-
/** Removes PIN to Drive. Requires the car to be in Pin to Drive mode and not in Valet mode. */
|
|
613
|
-
async reset_pin_to_drive_pin() {
|
|
614
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlResetPinToDriveAction: VehicleControlResetPinToDriveAction.create({}) }));
|
|
615
|
-
}
|
|
616
|
-
/** Removes PIN for Valet Mode. */
|
|
617
|
-
async reset_valet_pin() {
|
|
618
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlResetValetPinAction: VehicleControlResetValetPinAction.create({}) }));
|
|
619
|
-
}
|
|
620
|
-
/**
|
|
621
|
-
* Schedules a vehicle software update (over the air "OTA") to be installed in the future.
|
|
622
|
-
* @param offset_sec Offset in seconds
|
|
623
|
-
*/
|
|
624
|
-
async schedule_software_update(offset_sec) {
|
|
625
|
-
return this.vehicleAction(VehicleAction.create({
|
|
626
|
-
vehicleControlScheduleSoftwareUpdateAction: VehicleControlScheduleSoftwareUpdateAction.create({ offsetSec: offset_sec }),
|
|
627
|
-
}));
|
|
628
|
-
}
|
|
629
|
-
/**
|
|
630
|
-
* Turns Bioweapon Defense Mode on and off.
|
|
631
|
-
* @param on `true` or `false`
|
|
632
|
-
* @param manual_override `true` or `false`
|
|
633
|
-
*/
|
|
634
|
-
async set_bioweapon_mode(on, manual_override) {
|
|
635
|
-
return this.vehicleAction(VehicleAction.create({ hvacBioweaponModeAction: HvacBioweaponModeAction.create({ on, manualOverride: manual_override }) }));
|
|
636
|
-
}
|
|
637
|
-
/**
|
|
638
|
-
* Sets the vehicle overheat protection.
|
|
639
|
-
* @param on `true` or `false`
|
|
640
|
-
* @param fan_only `true` or `false`
|
|
641
|
-
*/
|
|
642
|
-
async set_cabin_overheat_protection(on, fan_only) {
|
|
643
|
-
return this.vehicleAction(VehicleAction.create({ setCabinOverheatProtectionAction: SetCabinOverheatProtectionAction.create({ on, fanOnly: fan_only }) }));
|
|
644
|
-
}
|
|
645
|
-
/**
|
|
646
|
-
* Sets the vehicle's charge limit to a custom percentage.
|
|
647
|
-
* @param percent Charge limit percentage typically between 50-100
|
|
648
|
-
*/
|
|
649
|
-
async set_charge_limit(percent) {
|
|
650
|
-
return this.vehicleAction(VehicleAction.create({ chargingSetLimitAction: ChargingSetLimitAction.create({ percent }) }));
|
|
651
|
-
}
|
|
652
|
-
/**
|
|
653
|
-
* Sets the charging amps.
|
|
654
|
-
* @param charging_amps Current limit in Amps typically between 5-32
|
|
655
|
-
*/
|
|
656
|
-
async set_charging_amps(charging_amps) {
|
|
657
|
-
return this.vehicleAction(VehicleAction.create({ setChargingAmpsAction: SetChargingAmpsAction.create({ chargingAmps: charging_amps }) }));
|
|
658
|
-
}
|
|
659
|
-
/**
|
|
660
|
-
* Enables climate keeper mode.
|
|
661
|
-
* @param climate_keeper_mode `0` is Off, `1` is Keep, `2` is Dog, `3` is Camp
|
|
662
|
-
*/
|
|
663
|
-
async set_climate_keeper_mode(climate_keeper_mode) {
|
|
664
|
-
const mode = typeof climate_keeper_mode === "string" ? ClimateModes[climate_keeper_mode] : climate_keeper_mode;
|
|
665
|
-
const action = ClimateKeeperActions[mode];
|
|
666
|
-
if (action === undefined) {
|
|
667
|
-
throw new Error(`Invalid climate keeper mode: ${climate_keeper_mode}`);
|
|
668
|
-
}
|
|
669
|
-
return this.vehicleAction(VehicleAction.create({ hvacClimateKeeperAction: { ClimateKeeperAction: action, manualOverride: false, manualOverrideMode: [] } }));
|
|
670
|
-
}
|
|
671
|
-
/**
|
|
672
|
-
* Adjusts the Cabin Overheat Protection temperature (COP).
|
|
673
|
-
* @param cop_temp Integer representing Low (0/30C/90F), Medium (1/35C/95F), or High (2/40C/100F)
|
|
674
|
-
*/
|
|
675
|
-
async set_cop_temp(cop_temp) {
|
|
676
|
-
const copActivationTemp = CopActivationTemps[cop_temp];
|
|
677
|
-
if (copActivationTemp === undefined) {
|
|
678
|
-
throw new Error(`Invalid cop_temp: ${cop_temp}`);
|
|
679
|
-
}
|
|
680
|
-
return this.vehicleAction(VehicleAction.create({ setCopTempAction: SetCopTempAction.create({ copActivationTemp }) }));
|
|
681
|
-
}
|
|
682
|
-
/**
|
|
683
|
-
* Sets a four-digit passcode for PIN to Drive.
|
|
684
|
-
* @param on `true` or `false`
|
|
685
|
-
* @param password Four-digit passcode
|
|
686
|
-
*/
|
|
687
|
-
async set_pin_to_drive(on, password) {
|
|
688
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlSetPinToDriveAction: VehicleControlSetPinToDriveAction.create({ on, password: String(password) }) }));
|
|
689
|
-
}
|
|
690
|
-
/**
|
|
691
|
-
* Sets an override for preconditioning — it should default to empty if no override is used.
|
|
692
|
-
* @param on `true` or `false`
|
|
693
|
-
* @param manual_override `true` or `false`
|
|
694
|
-
*/
|
|
695
|
-
async set_preconditioning_max(on, manual_override) {
|
|
696
|
-
return this.vehicleAction(VehicleAction.create({
|
|
697
|
-
hvacSetPreconditioningMaxAction: HvacSetPreconditioningMaxAction.create({ on, manualOverride: manual_override }),
|
|
698
|
-
}));
|
|
699
|
-
}
|
|
700
|
-
/**
|
|
701
|
-
* Sets a time at which charging should be completed.
|
|
702
|
-
* @param enable `true` or `false`
|
|
703
|
-
* @param time Minutes after midnight
|
|
704
|
-
*/
|
|
705
|
-
async set_scheduled_charging(enable, time) {
|
|
706
|
-
return this.vehicleAction(VehicleAction.create({ scheduledChargingAction: ScheduledChargingAction.create({ enabled: enable, chargingTime: time }) }));
|
|
707
|
-
}
|
|
708
|
-
/**
|
|
709
|
-
* Sets a time at which departure should be completed.
|
|
710
|
-
*
|
|
711
|
-
* `preconditioning_enabled` and `off_peak_charging_enabled` are accepted
|
|
712
|
-
* for cross-transport signature parity but have no field in the signed
|
|
713
|
-
* command protobuf, so they are not sent.
|
|
714
|
-
* @param enable `true` or `false`
|
|
715
|
-
* @param preconditioning_enabled not representable in a signed command
|
|
716
|
-
* @param preconditioning_weekdays_only `true` or `false`
|
|
717
|
-
* @param departure_time Minutes after midnight
|
|
718
|
-
* @param off_peak_charging_enabled not representable in a signed command
|
|
719
|
-
* @param off_peak_charging_weekdays_only `true` or `false`
|
|
720
|
-
* @param end_off_peak_time Minutes after midnight
|
|
721
|
-
*/
|
|
722
|
-
async set_scheduled_departure(enable = true, _preconditioning_enabled = false, preconditioning_weekdays_only = false, departure_time = 0, _off_peak_charging_enabled = false, off_peak_charging_weekdays_only = false, end_off_peak_time = 0) {
|
|
723
|
-
const preconditioningTimes = preconditioning_weekdays_only
|
|
724
|
-
? PreconditioningTimes.create({ weekdays: VOID })
|
|
725
|
-
: PreconditioningTimes.create({ allWeek: VOID });
|
|
726
|
-
const offPeakChargingTimes = off_peak_charging_weekdays_only
|
|
727
|
-
? OffPeakChargingTimes.create({ weekdays: VOID })
|
|
728
|
-
: OffPeakChargingTimes.create({ allWeek: VOID });
|
|
729
|
-
return this.vehicleAction(VehicleAction.create({
|
|
730
|
-
scheduledDepartureAction: ScheduledDepartureAction.create({
|
|
731
|
-
enabled: enable,
|
|
732
|
-
departureTime: departure_time,
|
|
733
|
-
preconditioningTimes,
|
|
734
|
-
offPeakChargingTimes,
|
|
735
|
-
offPeakHoursEndTime: end_off_peak_time,
|
|
736
|
-
}),
|
|
737
|
-
}));
|
|
738
|
-
}
|
|
739
|
-
/**
|
|
740
|
-
* Enables and disables Sentry Mode.
|
|
741
|
-
* @param on `true` or `false`
|
|
742
|
-
*/
|
|
743
|
-
async set_sentry_mode(on) {
|
|
744
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlSetSentryModeAction: VehicleControlSetSentryModeAction.create({ on }) }));
|
|
745
|
-
}
|
|
746
|
-
/**
|
|
747
|
-
* Sets the driver and/or passenger-side cabin temperature (and other zones if sync is enabled).
|
|
748
|
-
* @param driver_temp Driver temperature
|
|
749
|
-
* @param passenger_temp Passenger temperature
|
|
750
|
-
*/
|
|
751
|
-
async set_temps(driver_temp, passenger_temp) {
|
|
752
|
-
return this.vehicleAction(VehicleAction.create({
|
|
753
|
-
hvacTemperatureAdjustmentAction: HvacTemperatureAdjustmentAction.create({
|
|
754
|
-
driverTempCelsius: driver_temp,
|
|
755
|
-
passengerTempCelsius: passenger_temp,
|
|
756
|
-
}),
|
|
757
|
-
}));
|
|
758
|
-
}
|
|
759
|
-
/**
|
|
760
|
-
* Turns on Valet Mode and sets a four-digit passcode.
|
|
761
|
-
* @param on `true` or `false`
|
|
762
|
-
* @param password Four-digit passcode
|
|
763
|
-
*/
|
|
764
|
-
async set_valet_mode(on, password) {
|
|
765
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlSetValetModeAction: VehicleControlSetValetModeAction.create({ on, password: String(password) }) }));
|
|
766
|
-
}
|
|
767
|
-
/**
|
|
768
|
-
* Changes the name of a vehicle.
|
|
769
|
-
* @param vehicle_name New name
|
|
770
|
-
*/
|
|
771
|
-
async set_vehicle_name(vehicle_name) {
|
|
772
|
-
return this.vehicleAction(VehicleAction.create({ setVehicleNameAction: SetVehicleNameAction.create({ vehicleName: vehicle_name }) }));
|
|
773
|
-
}
|
|
774
|
-
/**
|
|
775
|
-
* Activates Speed Limit Mode with a four-digit PIN.
|
|
776
|
-
* @param pin Four-digit PIN
|
|
777
|
-
*/
|
|
778
|
-
async speed_limit_activate(pin) {
|
|
779
|
-
return this.vehicleAction(VehicleAction.create({ drivingSpeedLimitAction: DrivingSpeedLimitAction.create({ activate: true, pin: String(pin) }) }));
|
|
780
|
-
}
|
|
781
|
-
/**
|
|
782
|
-
* Deactivates Speed Limit Mode and resets the associated PIN.
|
|
783
|
-
* @param pin Four-digit PIN
|
|
784
|
-
*/
|
|
785
|
-
async speed_limit_clear_pin(pin) {
|
|
786
|
-
return this.vehicleAction(VehicleAction.create({ drivingClearSpeedLimitPinAction: DrivingClearSpeedLimitPinAction.create({ pin: String(pin) }) }));
|
|
787
|
-
}
|
|
788
|
-
/** Deactivates Speed Limit Mode and resets the associated PIN, for fleet managers or owners. */
|
|
789
|
-
async speed_limit_clear_pin_admin() {
|
|
790
|
-
return this.vehicleAction(VehicleAction.create({ drivingClearSpeedLimitPinAdminAction: DrivingClearSpeedLimitPinAdminAction.create({}) }));
|
|
791
|
-
}
|
|
792
|
-
/**
|
|
793
|
-
* Deactivates Speed Limit Mode.
|
|
794
|
-
* @param pin Four-digit PIN
|
|
795
|
-
*/
|
|
796
|
-
async speed_limit_deactivate(pin) {
|
|
797
|
-
return this.vehicleAction(VehicleAction.create({ drivingSpeedLimitAction: DrivingSpeedLimitAction.create({ activate: false, pin: String(pin) }) }));
|
|
798
|
-
}
|
|
799
|
-
/**
|
|
800
|
-
* Sets the maximum speed allowed when Speed Limit Mode is active.
|
|
801
|
-
* @param limit_mph Maximum speed in MPH
|
|
802
|
-
*/
|
|
803
|
-
async speed_limit_set_limit(limit_mph) {
|
|
804
|
-
return this.vehicleAction(VehicleAction.create({ drivingSetSpeedLimitAction: DrivingSetSpeedLimitAction.create({ limitMph: limit_mph }) }));
|
|
805
|
-
}
|
|
806
|
-
/**
|
|
807
|
-
* Controls the panoramic sunroof on the Model S.
|
|
808
|
-
*
|
|
809
|
-
* "stop" has no corresponding field in the signed-command protobuf (only
|
|
810
|
-
* vent/close/open), so it is rejected rather than guessed at.
|
|
811
|
-
* @param state "close" or "vent"
|
|
812
|
-
*/
|
|
813
|
-
async sun_roof_control(state) {
|
|
814
|
-
let action;
|
|
815
|
-
if (state === "vent") {
|
|
816
|
-
action = VehicleControlSunroofOpenCloseAction.create({ vent: VOID });
|
|
817
|
-
}
|
|
818
|
-
else if (state === "close") {
|
|
819
|
-
action = VehicleControlSunroofOpenCloseAction.create({ close: VOID });
|
|
820
|
-
}
|
|
821
|
-
else {
|
|
822
|
-
throw new Error('sun_roof_control: "stop" is not representable in a signed command.');
|
|
823
|
-
}
|
|
824
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlSunroofOpenCloseAction: action }));
|
|
825
|
-
}
|
|
826
|
-
/**
|
|
827
|
-
* Records a drive note. Overrides the inherited plaintext command so it is
|
|
828
|
-
* signed and dispatched over the vehicle-command protocol rather than
|
|
829
|
-
* silently falling through to the unsigned REST endpoint on vehicles that
|
|
830
|
-
* require signing.
|
|
831
|
-
* @param note Drive note
|
|
832
|
-
*/
|
|
833
|
-
async take_drivenote(note) {
|
|
834
|
-
return this.vehicleAction(VehicleAction.create({ takeDrivenoteAction: TakeDrivenoteAction.create({ note }) }));
|
|
835
|
-
}
|
|
836
|
-
/**
|
|
837
|
-
* Turns on HomeLink (used to open and close garage doors).
|
|
838
|
-
* @param lat Latitude
|
|
839
|
-
* @param lon Longitude
|
|
840
|
-
* @param token
|
|
841
|
-
*/
|
|
842
|
-
async trigger_homelink(lat, lon, token = "") {
|
|
843
|
-
return this.vehicleAction(VehicleAction.create({
|
|
844
|
-
vehicleControlTriggerHomelinkAction: VehicleControlTriggerHomelinkAction.create({
|
|
845
|
-
location: LatLong.create({ latitude: lat, longitude: lon }),
|
|
846
|
-
token,
|
|
847
|
-
}),
|
|
848
|
-
}));
|
|
849
|
-
}
|
|
850
|
-
/**
|
|
851
|
-
* Sends upcoming calendar entries to the vehicle. Overrides the inherited
|
|
852
|
-
* plaintext command so it is signed and dispatched over the vehicle-command
|
|
853
|
-
* protocol rather than silently falling through to the unsigned REST
|
|
854
|
-
* endpoint on vehicles that require signing.
|
|
855
|
-
* @param calendar_data Calendar data
|
|
856
|
-
*/
|
|
857
|
-
async upcoming_calendar_entries(calendar_data) {
|
|
858
|
-
return this.vehicleAction(VehicleAction.create({ uiSetUpcomingCalendarEntries: UiSetUpcomingCalendarEntries.create({ calendarData: calendar_data }) }));
|
|
859
|
-
}
|
|
860
|
-
/**
|
|
861
|
-
* Control the windows of a parked vehicle. Supported commands: vent and close.
|
|
862
|
-
* @param command "vent" or "close"
|
|
863
|
-
* @param lat Latitude
|
|
864
|
-
* @param lon Longitude
|
|
865
|
-
*/
|
|
866
|
-
async window_control(command, _lat, _lon) {
|
|
867
|
-
const action = command === "vent"
|
|
868
|
-
? VehicleControlWindowAction.create({ vent: VOID })
|
|
869
|
-
: VehicleControlWindowAction.create({ close: VOID });
|
|
870
|
-
return this.vehicleAction(VehicleAction.create({ vehicleControlWindowAction: action }));
|
|
871
|
-
}
|
|
872
|
-
}
|
|
873
|
-
_Commands_privateKey = new WeakMap(), _Commands_publicKey = new WeakMap();
|
|
874
|
-
export default Commands;
|
|
875
|
-
//# sourceMappingURL=commands.js.map
|