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
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"crypto.js","sourceRoot":"","sources":["../../src/signing/crypto.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,MAAM,KAAK,GAAG,YAAY,CAAC,CAAC,oDAAoD;AAEhF,+EAA+E;AAC/E,MAAM,UAAU,YAAY,CAAC,UAAkB;IAC3C,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAC/B,OAAO,IAAI,CAAC,YAAY,EAAE,CAAC;AAC/B,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,eAAe,CAAC,UAAkB,EAAE,gBAAwB;IACxE,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;IACtC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC,CAAC;IAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,aAAa,CAAC,gBAAgB,CAAC,CAAC;IACpD,OAAO,MAAM,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC7E,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,QAAQ,CAAC,KAAa;IAClC,MAAM,MAAM,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IAC/B,MAAM,CAAC,aAAa,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC;AAClB,CAAC"}
|
package/dist/signing/errors.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { MessageFaultE } from "@teslemetry/tesla-protocol/command/universal_message";
|
|
2
|
-
/**
|
|
3
|
-
* Base class for every error raised by the signed-command layer.
|
|
4
|
-
*/
|
|
5
|
-
export declare class SignedCommandError extends Error {
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* The vehicle rejected the session handshake because this key has not been
|
|
9
|
-
* paired with it (added via the Tesla app / NFC card).
|
|
10
|
-
*/
|
|
11
|
-
export declare class NotOnVehicleWhitelistError extends SignedCommandError {
|
|
12
|
-
constructor();
|
|
13
|
-
}
|
|
14
|
-
/**
|
|
15
|
-
* The vehicle rejected a signed command with a `MessageFaultE` other than
|
|
16
|
-
* `MESSAGEFAULT_ERROR_NONE`.
|
|
17
|
-
*/
|
|
18
|
-
export declare class SignedCommandFaultError extends SignedCommandError {
|
|
19
|
-
fault: MessageFaultE;
|
|
20
|
-
constructor(fault: MessageFaultE);
|
|
21
|
-
}
|
|
22
|
-
/**
|
|
23
|
-
* A `SignedCommandFaultError` whose fault the vehicle resolves by handing back
|
|
24
|
-
* fresh session info (epoch/counter drift) - `_command` retries these,
|
|
25
|
-
* bounded, by re-signing against the updated session before giving up.
|
|
26
|
-
*/
|
|
27
|
-
export declare class RetryableSignedCommandFaultError extends SignedCommandFaultError {
|
|
28
|
-
}
|
|
29
|
-
export declare function createFaultError(fault: MessageFaultE): SignedCommandFaultError;
|
package/dist/signing/errors.js
DELETED
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import { MessageFaultE, messageFaultEToJSON } from "@teslemetry/tesla-protocol/command/universal_message";
|
|
2
|
-
/**
|
|
3
|
-
* Base class for every error raised by the signed-command layer.
|
|
4
|
-
*/
|
|
5
|
-
export class SignedCommandError extends Error {
|
|
6
|
-
}
|
|
7
|
-
/**
|
|
8
|
-
* The vehicle rejected the session handshake because this key has not been
|
|
9
|
-
* paired with it (added via the Tesla app / NFC card).
|
|
10
|
-
*/
|
|
11
|
-
export class NotOnVehicleWhitelistError extends SignedCommandError {
|
|
12
|
-
constructor() {
|
|
13
|
-
super("This public key is not on the vehicle's key whitelist. Pair it with the vehicle first.");
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
/**
|
|
17
|
-
* The vehicle rejected a signed command with a `MessageFaultE` other than
|
|
18
|
-
* `MESSAGEFAULT_ERROR_NONE`.
|
|
19
|
-
*/
|
|
20
|
-
export class SignedCommandFaultError extends SignedCommandError {
|
|
21
|
-
constructor(fault) {
|
|
22
|
-
super(`Vehicle rejected signed command: ${messageFaultEToJSON(fault)}`);
|
|
23
|
-
this.fault = fault;
|
|
24
|
-
}
|
|
25
|
-
}
|
|
26
|
-
/**
|
|
27
|
-
* A `SignedCommandFaultError` whose fault the vehicle resolves by handing back
|
|
28
|
-
* fresh session info (epoch/counter drift) - `_command` retries these,
|
|
29
|
-
* bounded, by re-signing against the updated session before giving up.
|
|
30
|
-
*/
|
|
31
|
-
export class RetryableSignedCommandFaultError extends SignedCommandFaultError {
|
|
32
|
-
}
|
|
33
|
-
export function createFaultError(fault) {
|
|
34
|
-
if (fault === MessageFaultE.MESSAGEFAULT_ERROR_INCORRECT_EPOCH ||
|
|
35
|
-
fault === MessageFaultE.MESSAGEFAULT_ERROR_INVALID_TOKEN_OR_COUNTER) {
|
|
36
|
-
return new RetryableSignedCommandFaultError(fault);
|
|
37
|
-
}
|
|
38
|
-
return new SignedCommandFaultError(fault);
|
|
39
|
-
}
|
|
40
|
-
//# sourceMappingURL=errors.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errors.js","sourceRoot":"","sources":["../../src/signing/errors.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,mBAAmB,EAAE,MAAM,sDAAsD,CAAC;AAE1G;;GAEG;AACH,MAAM,OAAO,kBAAmB,SAAQ,KAAK;CAAG;AAEhD;;;GAGG;AACH,MAAM,OAAO,0BAA2B,SAAQ,kBAAkB;IAC9D;QACI,KAAK,CACD,wFAAwF,CAC3F,CAAC;IACN,CAAC;CACJ;AAED;;;GAGG;AACH,MAAM,OAAO,uBAAwB,SAAQ,kBAAkB;IAG3D,YAAY,KAAoB;QAC5B,KAAK,CAAC,oCAAoC,mBAAmB,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QACxE,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;IACvB,CAAC;CACJ;AAED;;;;GAIG;AACH,MAAM,OAAO,gCAAiC,SAAQ,uBAAuB;CAAG;AAEhF,MAAM,UAAU,gBAAgB,CAC5B,KAAoB;IAEpB,IACI,KAAK,KAAK,aAAa,CAAC,kCAAkC;QAC1D,KAAK,KAAK,aAAa,CAAC,2CAA2C,EACrE,CAAC;QACC,OAAO,IAAI,gCAAgC,CAAC,KAAK,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,IAAI,uBAAuB,CAAC,KAAK,CAAC,CAAC;AAC9C,CAAC"}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
import { Domain } from "@teslemetry/tesla-protocol/command/universal_message";
|
|
2
|
-
import { HMACPersonalizedSignatureData, SessionInfo } from "@teslemetry/tesla-protocol/command/signatures";
|
|
3
|
-
/** Key material derived (but not yet trusted/committed) for a candidate vehicle public key. */
|
|
4
|
-
export interface SessionKeys {
|
|
5
|
-
sharedKey: Buffer;
|
|
6
|
-
hmacKey: Buffer;
|
|
7
|
-
sessionInfoKey: Buffer;
|
|
8
|
-
}
|
|
9
|
-
/**
|
|
10
|
-
* Per-domain (VCSEC / Infotainment) signed-command session: tracks the
|
|
11
|
-
* anti-replay counter/epoch handed out by the vehicle's handshake reply and
|
|
12
|
-
* the HMAC keys derived from it.
|
|
13
|
-
*
|
|
14
|
-
* Deriving key material (`keysFor`) is split from committing it (`commit`)
|
|
15
|
-
* because the caller must authenticate a `SessionInfo` reply - by verifying
|
|
16
|
-
* its `session_info_tag` against the very keys derived here - *before*
|
|
17
|
-
* trusting anything in it, including the vehicle public key the shared key
|
|
18
|
-
* itself is derived from. See `Commands.validateAndUpdateSession`.
|
|
19
|
-
*
|
|
20
|
-
* A `Session` is not itself thread-safe; `withLock` serializes the
|
|
21
|
-
* message-build step (which mutates `counter`) so concurrent commands on the
|
|
22
|
-
* same domain cannot race on the same counter value.
|
|
23
|
-
*/
|
|
24
|
-
export declare class Session {
|
|
25
|
-
private readonly deriveSharedKey;
|
|
26
|
-
readonly domain: Domain;
|
|
27
|
-
counter: number;
|
|
28
|
-
epoch?: Buffer;
|
|
29
|
-
delta?: number;
|
|
30
|
-
sharedKey?: Buffer;
|
|
31
|
-
hmacKey?: Buffer;
|
|
32
|
-
sessionInfoKey?: Buffer;
|
|
33
|
-
publicKey?: Buffer;
|
|
34
|
-
/** Clock time of the last *authenticated* SessionInfo committed for the current epoch, guarding against replay/rollback. */
|
|
35
|
-
private lastAuthenticatedClockTime?;
|
|
36
|
-
private queue;
|
|
37
|
-
constructor(domain: Domain, deriveSharedKey: (vehiclePublicKey: Buffer) => Buffer);
|
|
38
|
-
/** Whether the handshake has completed and commands can be signed. */
|
|
39
|
-
get ready(): boolean;
|
|
40
|
-
/**
|
|
41
|
-
* Derive the shared key and its two HMAC sub-keys for a candidate vehicle
|
|
42
|
-
* public key, without touching any session state. Pure and side-effect
|
|
43
|
-
* free so a caller can verify authenticity first and discard the result
|
|
44
|
-
* if verification fails.
|
|
45
|
-
*/
|
|
46
|
-
keysFor(vehiclePublicKey: Buffer): SessionKeys;
|
|
47
|
-
/**
|
|
48
|
-
* Commit an already-authenticated `SessionInfo` plus the `keysFor` result
|
|
49
|
-
* derived from its public key. Per the vehicle-command protocol, the
|
|
50
|
-
* anti-replay counter must never roll back within the same epoch, and a
|
|
51
|
-
* clock time that regresses within the same epoch marks the reply as
|
|
52
|
-
* stale/replayed - returns `false` (without mutating any state) in that
|
|
53
|
-
* case so the caller can reject it.
|
|
54
|
-
*/
|
|
55
|
-
commit(sessionInfo: SessionInfo, keys: SessionKeys): boolean;
|
|
56
|
-
/**
|
|
57
|
-
* Advance the anti-replay counter and return fresh signature metadata for
|
|
58
|
-
* an HMAC-personalized command. The command expires 10 seconds from now,
|
|
59
|
-
* corrected for clock drift against the vehicle (`delta`).
|
|
60
|
-
*/
|
|
61
|
-
hmacPersonalized(): HMACPersonalizedSignatureData;
|
|
62
|
-
/**
|
|
63
|
-
* Run `fn` with exclusive access to this session, queuing behind any
|
|
64
|
-
* in-flight caller. Held only for as long as `fn` takes - callers should
|
|
65
|
-
* keep it scoped to the synchronous message-build step, not a full
|
|
66
|
-
* network round trip.
|
|
67
|
-
*/
|
|
68
|
-
withLock<T>(fn: () => T | Promise<T>): Promise<T>;
|
|
69
|
-
}
|
package/dist/signing/session.js
DELETED
|
@@ -1,102 +0,0 @@
|
|
|
1
|
-
import crypto from "crypto";
|
|
2
|
-
import { HMACPersonalizedSignatureData, } from "@teslemetry/tesla-protocol/command/signatures";
|
|
3
|
-
/**
|
|
4
|
-
* Per-domain (VCSEC / Infotainment) signed-command session: tracks the
|
|
5
|
-
* anti-replay counter/epoch handed out by the vehicle's handshake reply and
|
|
6
|
-
* the HMAC keys derived from it.
|
|
7
|
-
*
|
|
8
|
-
* Deriving key material (`keysFor`) is split from committing it (`commit`)
|
|
9
|
-
* because the caller must authenticate a `SessionInfo` reply - by verifying
|
|
10
|
-
* its `session_info_tag` against the very keys derived here - *before*
|
|
11
|
-
* trusting anything in it, including the vehicle public key the shared key
|
|
12
|
-
* itself is derived from. See `Commands.validateAndUpdateSession`.
|
|
13
|
-
*
|
|
14
|
-
* A `Session` is not itself thread-safe; `withLock` serializes the
|
|
15
|
-
* message-build step (which mutates `counter`) so concurrent commands on the
|
|
16
|
-
* same domain cannot race on the same counter value.
|
|
17
|
-
*/
|
|
18
|
-
export class Session {
|
|
19
|
-
constructor(domain, deriveSharedKey) {
|
|
20
|
-
this.deriveSharedKey = deriveSharedKey;
|
|
21
|
-
this.counter = 0;
|
|
22
|
-
this.queue = Promise.resolve();
|
|
23
|
-
this.domain = domain;
|
|
24
|
-
}
|
|
25
|
-
/** Whether the handshake has completed and commands can be signed. */
|
|
26
|
-
get ready() {
|
|
27
|
-
return this.epoch !== undefined && this.hmacKey !== undefined && this.delta !== undefined;
|
|
28
|
-
}
|
|
29
|
-
/**
|
|
30
|
-
* Derive the shared key and its two HMAC sub-keys for a candidate vehicle
|
|
31
|
-
* public key, without touching any session state. Pure and side-effect
|
|
32
|
-
* free so a caller can verify authenticity first and discard the result
|
|
33
|
-
* if verification fails.
|
|
34
|
-
*/
|
|
35
|
-
keysFor(vehiclePublicKey) {
|
|
36
|
-
const sharedKey = this.deriveSharedKey(vehiclePublicKey);
|
|
37
|
-
const hmacKey = crypto.createHmac("sha256", sharedKey).update("authenticated command").digest();
|
|
38
|
-
const sessionInfoKey = crypto.createHmac("sha256", sharedKey).update("session info").digest();
|
|
39
|
-
return { sharedKey, hmacKey, sessionInfoKey };
|
|
40
|
-
}
|
|
41
|
-
/**
|
|
42
|
-
* Commit an already-authenticated `SessionInfo` plus the `keysFor` result
|
|
43
|
-
* derived from its public key. Per the vehicle-command protocol, the
|
|
44
|
-
* anti-replay counter must never roll back within the same epoch, and a
|
|
45
|
-
* clock time that regresses within the same epoch marks the reply as
|
|
46
|
-
* stale/replayed - returns `false` (without mutating any state) in that
|
|
47
|
-
* case so the caller can reject it.
|
|
48
|
-
*/
|
|
49
|
-
commit(sessionInfo, keys) {
|
|
50
|
-
const incomingEpoch = Buffer.from(sessionInfo.epoch);
|
|
51
|
-
const sameEpoch = this.epoch !== undefined && this.epoch.equals(incomingEpoch);
|
|
52
|
-
if (sameEpoch && this.lastAuthenticatedClockTime !== undefined && sessionInfo.clockTime < this.lastAuthenticatedClockTime) {
|
|
53
|
-
return false;
|
|
54
|
-
}
|
|
55
|
-
this.counter = sameEpoch ? Math.max(this.counter, sessionInfo.counter) : sessionInfo.counter;
|
|
56
|
-
this.epoch = incomingEpoch;
|
|
57
|
-
this.delta = Math.floor(Date.now() / 1000) - sessionInfo.clockTime;
|
|
58
|
-
this.lastAuthenticatedClockTime = sessionInfo.clockTime;
|
|
59
|
-
this.publicKey = Buffer.from(sessionInfo.publicKey);
|
|
60
|
-
this.sharedKey = keys.sharedKey;
|
|
61
|
-
this.hmacKey = keys.hmacKey;
|
|
62
|
-
this.sessionInfoKey = keys.sessionInfoKey;
|
|
63
|
-
return true;
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Advance the anti-replay counter and return fresh signature metadata for
|
|
67
|
-
* an HMAC-personalized command. The command expires 10 seconds from now,
|
|
68
|
-
* corrected for clock drift against the vehicle (`delta`).
|
|
69
|
-
*/
|
|
70
|
-
hmacPersonalized() {
|
|
71
|
-
if (!this.ready || !this.epoch || this.delta === undefined) {
|
|
72
|
-
throw new Error("Session is not ready: perform the handshake first.");
|
|
73
|
-
}
|
|
74
|
-
this.counter++;
|
|
75
|
-
return HMACPersonalizedSignatureData.create({
|
|
76
|
-
epoch: this.epoch,
|
|
77
|
-
counter: this.counter,
|
|
78
|
-
expiresAt: Math.floor(Date.now() / 1000) - this.delta + 10,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
/**
|
|
82
|
-
* Run `fn` with exclusive access to this session, queuing behind any
|
|
83
|
-
* in-flight caller. Held only for as long as `fn` takes - callers should
|
|
84
|
-
* keep it scoped to the synchronous message-build step, not a full
|
|
85
|
-
* network round trip.
|
|
86
|
-
*/
|
|
87
|
-
async withLock(fn) {
|
|
88
|
-
const previous = this.queue;
|
|
89
|
-
let release;
|
|
90
|
-
this.queue = new Promise((resolve) => {
|
|
91
|
-
release = resolve;
|
|
92
|
-
});
|
|
93
|
-
await previous.catch(() => undefined);
|
|
94
|
-
try {
|
|
95
|
-
return await fn();
|
|
96
|
-
}
|
|
97
|
-
finally {
|
|
98
|
-
release();
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
//# sourceMappingURL=session.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"session.js","sourceRoot":"","sources":["../../src/signing/session.ts"],"names":[],"mappings":"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"}
|
package/dist/tariff.d.ts
DELETED
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { TariffContentV2 } from "./types/site_info.js";
|
|
2
|
-
export interface TariffRate {
|
|
3
|
-
price: number | null;
|
|
4
|
-
periodName: string | null;
|
|
5
|
-
seasonName: string | null;
|
|
6
|
-
}
|
|
7
|
-
export interface TariffPeriod {
|
|
8
|
-
start: Date;
|
|
9
|
-
end: Date;
|
|
10
|
-
buy: TariffRate;
|
|
11
|
-
sell: TariffRate;
|
|
12
|
-
}
|
|
13
|
-
export interface TariffResolution {
|
|
14
|
-
buy: TariffRate;
|
|
15
|
-
sell: TariffRate;
|
|
16
|
-
currentStart: Date;
|
|
17
|
-
nextChange: Date;
|
|
18
|
-
currency: string | null;
|
|
19
|
-
upcoming: TariffPeriod[] | null;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* Resolves the current buy/sell time-of-use rate for a Tariff V2 object at a given instant.
|
|
23
|
-
* `tariff` carries no timezone; the caller must supply the site's IANA zone (e.g. from
|
|
24
|
-
* `site_info.installation_time_zone`) so wall-clock period boundaries match correctly.
|
|
25
|
-
*/
|
|
26
|
-
export declare function getTariffPeriods(tariff: TariffContentV2, now: Date, opts?: {
|
|
27
|
-
timeZone: string;
|
|
28
|
-
horizonHours?: number;
|
|
29
|
-
}): TariffResolution | null;
|
package/dist/tariff.js
DELETED
|
@@ -1,302 +0,0 @@
|
|
|
1
|
-
const MINUTES_PER_DAY = 1440;
|
|
2
|
-
function formatParts(date, timeZone) {
|
|
3
|
-
const parts = new Intl.DateTimeFormat("en-US", {
|
|
4
|
-
timeZone,
|
|
5
|
-
year: "numeric",
|
|
6
|
-
month: "2-digit",
|
|
7
|
-
day: "2-digit",
|
|
8
|
-
hour: "2-digit",
|
|
9
|
-
minute: "2-digit",
|
|
10
|
-
second: "2-digit",
|
|
11
|
-
hourCycle: "h23",
|
|
12
|
-
}).formatToParts(date);
|
|
13
|
-
const out = {};
|
|
14
|
-
for (const p of parts)
|
|
15
|
-
out[p.type] = Number(p.value);
|
|
16
|
-
return out;
|
|
17
|
-
}
|
|
18
|
-
/** Tesla weekday (Mon=0..Sun=6) for a calendar date, via JS Date.getUTCDay() (Sun=0..Sat=6). */
|
|
19
|
-
function dowFromDate(year, month, day) {
|
|
20
|
-
const jsDow = new Date(Date.UTC(year, month - 1, day)).getUTCDay();
|
|
21
|
-
return (jsDow + 6) % 7;
|
|
22
|
-
}
|
|
23
|
-
function getWallClock(now, timeZone) {
|
|
24
|
-
const { year, month, day, hour, minute } = formatParts(now, timeZone);
|
|
25
|
-
return { year, month, day, dow: dowFromDate(year, month, day), minuteOfDay: hour * 60 + minute };
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Converts a target site-local wall-clock (year/month/day/hour/minute in `timeZone`) to the UTC
|
|
29
|
-
* instant it represents. Iterates because the zone's UTC offset at the target instant is itself
|
|
30
|
-
* what we're solving for (DST) - 3 rounds converges for any real-world offset change.
|
|
31
|
-
*/
|
|
32
|
-
function wallClockToUtcMillis(year, month, day, hour, minute, timeZone) {
|
|
33
|
-
const target = Date.UTC(year, month - 1, day, hour, minute);
|
|
34
|
-
let guess = target;
|
|
35
|
-
for (let i = 0; i < 3; i++) {
|
|
36
|
-
const p = formatParts(new Date(guess), timeZone);
|
|
37
|
-
const asUtc = Date.UTC(p.year, p.month - 1, p.day, p.hour, p.minute, p.second);
|
|
38
|
-
const offset = asUtc - guess;
|
|
39
|
-
const next = target - offset;
|
|
40
|
-
if (next === guess)
|
|
41
|
-
break;
|
|
42
|
-
guess = next;
|
|
43
|
-
}
|
|
44
|
-
return guess;
|
|
45
|
-
}
|
|
46
|
-
/**
|
|
47
|
-
* Adds `deltaMinutes` of wall-clock time (not elapsed real time) to a wall-clock reading, staying
|
|
48
|
-
* in pure calendar arithmetic throughout - no `timeZone`/`Intl` round trip, so this is safe to use
|
|
49
|
-
* for "what day/weekday is N minutes from now" even across a DST transition, where a real-time-ms
|
|
50
|
-
* shift and a wall-clock-minutes shift land on different calendar days.
|
|
51
|
-
*/
|
|
52
|
-
function wallClockAt(wallClock, deltaMinutes) {
|
|
53
|
-
const naive = new Date(Date.UTC(wallClock.year, wallClock.month - 1, wallClock.day, 0, wallClock.minuteOfDay + deltaMinutes));
|
|
54
|
-
const year = naive.getUTCFullYear();
|
|
55
|
-
const month = naive.getUTCMonth() + 1;
|
|
56
|
-
const day = naive.getUTCDate();
|
|
57
|
-
const minuteOfDay = naive.getUTCHours() * 60 + naive.getUTCMinutes();
|
|
58
|
-
return { year, month, day, dow: dowFromDate(year, month, day), minuteOfDay };
|
|
59
|
-
}
|
|
60
|
-
function dowInRange(d, fromDow, toDow) {
|
|
61
|
-
return fromDow <= toDow ? d >= fromDow && d <= toDow : d >= fromDow || d <= toDow;
|
|
62
|
-
}
|
|
63
|
-
function seasonContains(season, month, day) {
|
|
64
|
-
if (!season?.tou_periods)
|
|
65
|
-
return false;
|
|
66
|
-
const fromMonth = season.fromMonth ?? 1;
|
|
67
|
-
const fromDay = season.fromDay ?? 1;
|
|
68
|
-
const toMonth = season.toMonth ?? 12;
|
|
69
|
-
const toDay = season.toDay ?? 31;
|
|
70
|
-
const from = fromMonth * 100 + fromDay;
|
|
71
|
-
const to = toMonth * 100 + toDay;
|
|
72
|
-
const cur = month * 100 + day;
|
|
73
|
-
return from <= to ? cur >= from && cur <= to : cur >= from || cur <= to;
|
|
74
|
-
}
|
|
75
|
-
function findSeason(seasons, month, day) {
|
|
76
|
-
if (!seasons)
|
|
77
|
-
return null;
|
|
78
|
-
for (const [name, season] of Object.entries(seasons)) {
|
|
79
|
-
if (seasonContains(season, month, day)) {
|
|
80
|
-
return { name, season };
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
return null;
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Expands a season's `tou_periods` into the windows active on one specific calendar day (given
|
|
87
|
-
* as a Tesla weekday, Mon=0..Sun=6). A period whose `fromDayOfWeek..toDayOfWeek` includes `dow`
|
|
88
|
-
* contributes its own window (clamped to this day, `endMin` capped at 1440 if it crosses
|
|
89
|
-
* midnight); a period that crosses midnight and includes *yesterday* also contributes its
|
|
90
|
-
* early-morning continuation here, `trueStartMin` carrying its real (pre-midnight) start so a
|
|
91
|
-
* currently-active continuation can still report an accurate `currentStart`.
|
|
92
|
-
*/
|
|
93
|
-
function dayPeriods(touPeriods, dow) {
|
|
94
|
-
const segments = [];
|
|
95
|
-
const prevDow = (dow + 6) % 7;
|
|
96
|
-
for (const [periodName, def] of Object.entries(touPeriods)) {
|
|
97
|
-
for (const window of def.periods ?? []) {
|
|
98
|
-
const fromDow = window.fromDayOfWeek ?? 0;
|
|
99
|
-
const toDow = window.toDayOfWeek ?? 6;
|
|
100
|
-
const fromMin = (window.fromHour ?? 0) * 60 + (window.fromMinute ?? 0);
|
|
101
|
-
const toMin = (window.toHour ?? 0) * 60 + (window.toMinute ?? 0);
|
|
102
|
-
const crossesMidnight = toMin <= fromMin;
|
|
103
|
-
if (dowInRange(dow, fromDow, toDow)) {
|
|
104
|
-
const endMin = crossesMidnight ? MINUTES_PER_DAY : toMin;
|
|
105
|
-
if (endMin > fromMin)
|
|
106
|
-
segments.push({ periodName, startMin: fromMin, endMin, trueStartMin: fromMin });
|
|
107
|
-
}
|
|
108
|
-
if (crossesMidnight && toMin > 0 && dowInRange(prevDow, fromDow, toDow)) {
|
|
109
|
-
segments.push({ periodName, startMin: 0, endMin: toMin, trueStartMin: fromMin - MINUTES_PER_DAY });
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
return segments;
|
|
114
|
-
}
|
|
115
|
-
function lookupPrice(charges, seasonName, periodName) {
|
|
116
|
-
if (!charges)
|
|
117
|
-
return null;
|
|
118
|
-
// A season key can be present but carry no rates at all (e.g. an empty `"Winter": {}` stub
|
|
119
|
-
// alongside a populated `"ALL"`) - that must fall back to ALL exactly like a missing key.
|
|
120
|
-
const seasonRates = charges[seasonName]?.rates ?? charges["ALL"]?.rates;
|
|
121
|
-
if (!seasonRates)
|
|
122
|
-
return null;
|
|
123
|
-
const value = Object.prototype.hasOwnProperty.call(seasonRates, periodName) ? seasonRates[periodName] : seasonRates["ALL"];
|
|
124
|
-
return typeof value === "number" && Number.isFinite(value) ? value : null;
|
|
125
|
-
}
|
|
126
|
-
const EMPTY_RATE = { price: null, periodName: null, seasonName: null };
|
|
127
|
-
/**
|
|
128
|
-
* Resolves one grid's (buy's, or sell's) state at `wallClock`: the active period if any, and the
|
|
129
|
-
* next boundary regardless of whether a period is currently active - a sparse tariff's gap still
|
|
130
|
-
* has a "next change" (the gap's own end) and a "since" (the gap's own start), just like an active
|
|
131
|
-
* period does (its own end and start).
|
|
132
|
-
*/
|
|
133
|
-
function scheduleAt(seasons, wallClock) {
|
|
134
|
-
const matched = findSeason(seasons, wallClock.month, wallClock.day);
|
|
135
|
-
if (!matched)
|
|
136
|
-
return null;
|
|
137
|
-
const todaySegs = dayPeriods(matched.season.tou_periods, wallClock.dow);
|
|
138
|
-
const current = todaySegs.find((s) => s.startMin <= wallClock.minuteOfDay && wallClock.minuteOfDay < s.endMin) ?? null;
|
|
139
|
-
const laterTodayStarts = todaySegs.filter((s) => s.startMin > wallClock.minuteOfDay).map((s) => s.startMin);
|
|
140
|
-
let nextMin = current ? current.endMin : null;
|
|
141
|
-
if (laterTodayStarts.length > 0) {
|
|
142
|
-
nextMin = nextMin === null ? Math.min(...laterTodayStarts) : Math.min(nextMin, Math.min(...laterTodayStarts));
|
|
143
|
-
}
|
|
144
|
-
else if (nextMin === null || nextMin >= MINUTES_PER_DAY) {
|
|
145
|
-
// Either in a gap with nothing left today, or the active period runs up to midnight -
|
|
146
|
-
// check tomorrow before treating midnight itself as the boundary.
|
|
147
|
-
const tomorrowWallClock = wallClockAt(wallClock, MINUTES_PER_DAY - wallClock.minuteOfDay);
|
|
148
|
-
const tomorrowMatched = findSeason(seasons, tomorrowWallClock.month, tomorrowWallClock.day);
|
|
149
|
-
const tomorrowSegs = tomorrowMatched ? dayPeriods(tomorrowMatched.season.tou_periods, tomorrowWallClock.dow) : [];
|
|
150
|
-
const continuation = current && tomorrowMatched?.name === matched.name ? tomorrowSegs.find((s) => s.startMin === 0 && s.periodName === current.periodName) : undefined;
|
|
151
|
-
if (continuation) {
|
|
152
|
-
nextMin = MINUTES_PER_DAY + continuation.endMin;
|
|
153
|
-
}
|
|
154
|
-
else if (tomorrowSegs.length > 0) {
|
|
155
|
-
const tomorrowFirst = MINUTES_PER_DAY + Math.min(...tomorrowSegs.map((s) => s.startMin));
|
|
156
|
-
nextMin = nextMin === null ? tomorrowFirst : Math.min(nextMin, tomorrowFirst);
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
let sinceMin;
|
|
160
|
-
if (current) {
|
|
161
|
-
sinceMin = current.trueStartMin;
|
|
162
|
-
}
|
|
163
|
-
else {
|
|
164
|
-
const earlierTodayEnds = todaySegs.filter((s) => s.endMin <= wallClock.minuteOfDay).map((s) => s.endMin);
|
|
165
|
-
if (earlierTodayEnds.length > 0) {
|
|
166
|
-
sinceMin = Math.max(...earlierTodayEnds);
|
|
167
|
-
}
|
|
168
|
-
else {
|
|
169
|
-
// Nothing has ended yet today either - the gap may have started yesterday (or earlier).
|
|
170
|
-
// Peek one day back, same one-day bound as the forward "tomorrow" check above.
|
|
171
|
-
const yesterdayWallClock = wallClockAt(wallClock, -MINUTES_PER_DAY);
|
|
172
|
-
const yesterdayMatched = findSeason(seasons, yesterdayWallClock.month, yesterdayWallClock.day);
|
|
173
|
-
const yesterdaySegs = yesterdayMatched ? dayPeriods(yesterdayMatched.season.tou_periods, yesterdayWallClock.dow) : [];
|
|
174
|
-
sinceMin = yesterdaySegs.length > 0 ? Math.max(...yesterdaySegs.map((s) => s.endMin)) - MINUTES_PER_DAY : null;
|
|
175
|
-
}
|
|
176
|
-
}
|
|
177
|
-
return {
|
|
178
|
-
seasonName: matched.name,
|
|
179
|
-
current,
|
|
180
|
-
nextChangeGM: nextMin === null ? null : nextMin - wallClock.minuteOfDay,
|
|
181
|
-
sinceGM: sinceMin === null ? null : sinceMin - wallClock.minuteOfDay,
|
|
182
|
-
};
|
|
183
|
-
}
|
|
184
|
-
/** Walks one calendar day at a time across the horizon, re-resolving the season fresh on each day (via pure wall-clock arithmetic, not elapsed-ms/DST-sensitive arithmetic) so a horizon crossing a season boundary re-prices and re-labels correctly. */
|
|
185
|
-
function collectSegments(seasons, wallClock, horizonMinutes) {
|
|
186
|
-
const segments = [];
|
|
187
|
-
let dayStartGM = -wallClock.minuteOfDay;
|
|
188
|
-
while (dayStartGM < horizonMinutes) {
|
|
189
|
-
const dayWallClock = wallClockAt(wallClock, dayStartGM);
|
|
190
|
-
const matched = findSeason(seasons, dayWallClock.month, dayWallClock.day);
|
|
191
|
-
if (matched) {
|
|
192
|
-
for (const seg of dayPeriods(matched.season.tou_periods, dayWallClock.dow)) {
|
|
193
|
-
const startGM = dayStartGM + seg.startMin;
|
|
194
|
-
const endGM = dayStartGM + seg.endMin;
|
|
195
|
-
if (endGM > 0 && startGM < horizonMinutes) {
|
|
196
|
-
segments.push({ startGM, endGM, periodName: seg.periodName, seasonName: matched.name });
|
|
197
|
-
}
|
|
198
|
-
}
|
|
199
|
-
}
|
|
200
|
-
dayStartGM += MINUTES_PER_DAY;
|
|
201
|
-
}
|
|
202
|
-
segments.sort((a, b) => a.startGM - b.startGM);
|
|
203
|
-
const merged = [];
|
|
204
|
-
for (const seg of segments) {
|
|
205
|
-
const last = merged[merged.length - 1];
|
|
206
|
-
if (last && last.endGM === seg.startGM && last.periodName === seg.periodName && last.seasonName === seg.seasonName) {
|
|
207
|
-
last.endGM = seg.endGM;
|
|
208
|
-
}
|
|
209
|
-
else {
|
|
210
|
-
merged.push({ ...seg });
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
return merged;
|
|
214
|
-
}
|
|
215
|
-
function buildUpcoming(buySeasons, buyCharges, sellSeasons, sellCharges, hasSell, wallClock, horizonMinutes, toDate) {
|
|
216
|
-
const buySegs = collectSegments(buySeasons, wallClock, horizonMinutes);
|
|
217
|
-
const sellSegs = hasSell ? collectSegments(sellSeasons, wallClock, horizonMinutes) : [];
|
|
218
|
-
const boundaries = new Set([0, horizonMinutes]);
|
|
219
|
-
const addBoundary = (gm) => {
|
|
220
|
-
if (gm > 0 && gm < horizonMinutes)
|
|
221
|
-
boundaries.add(gm);
|
|
222
|
-
};
|
|
223
|
-
for (const s of buySegs) {
|
|
224
|
-
addBoundary(s.startGM);
|
|
225
|
-
addBoundary(s.endGM);
|
|
226
|
-
}
|
|
227
|
-
for (const s of sellSegs) {
|
|
228
|
-
addBoundary(s.startGM);
|
|
229
|
-
addBoundary(s.endGM);
|
|
230
|
-
}
|
|
231
|
-
const sorted = [...boundaries].sort((a, b) => a - b);
|
|
232
|
-
const periods = [];
|
|
233
|
-
for (let i = 0; i < sorted.length - 1; i++) {
|
|
234
|
-
const segStart = sorted[i];
|
|
235
|
-
const segEnd = sorted[i + 1];
|
|
236
|
-
if (segStart === segEnd)
|
|
237
|
-
continue;
|
|
238
|
-
const buyAt = buySegs.find((s) => s.startGM <= segStart && segStart < s.endGM);
|
|
239
|
-
const sellAt = sellSegs.find((s) => s.startGM <= segStart && segStart < s.endGM);
|
|
240
|
-
periods.push({
|
|
241
|
-
start: toDate(segStart),
|
|
242
|
-
end: toDate(segEnd),
|
|
243
|
-
buy: buyAt ? { price: lookupPrice(buyCharges, buyAt.seasonName, buyAt.periodName), periodName: buyAt.periodName, seasonName: buyAt.seasonName } : EMPTY_RATE,
|
|
244
|
-
sell: sellAt ? { price: lookupPrice(sellCharges, sellAt.seasonName, sellAt.periodName), periodName: sellAt.periodName, seasonName: sellAt.seasonName } : EMPTY_RATE,
|
|
245
|
-
});
|
|
246
|
-
}
|
|
247
|
-
return periods;
|
|
248
|
-
}
|
|
249
|
-
/**
|
|
250
|
-
* Resolves the current buy/sell time-of-use rate for a Tariff V2 object at a given instant.
|
|
251
|
-
* `tariff` carries no timezone; the caller must supply the site's IANA zone (e.g. from
|
|
252
|
-
* `site_info.installation_time_zone`) so wall-clock period boundaries match correctly.
|
|
253
|
-
*/
|
|
254
|
-
export function getTariffPeriods(tariff, now, opts) {
|
|
255
|
-
if (!tariff?.seasons || !tariff?.energy_charges)
|
|
256
|
-
return null;
|
|
257
|
-
if (!opts?.timeZone)
|
|
258
|
-
throw new Error("getTariffPeriods requires opts.timeZone");
|
|
259
|
-
const timeZone = opts.timeZone;
|
|
260
|
-
const wallClock = getWallClock(now, timeZone);
|
|
261
|
-
const buySchedule = scheduleAt(tariff.seasons, wallClock);
|
|
262
|
-
if (!buySchedule?.current)
|
|
263
|
-
return null;
|
|
264
|
-
const sellSeasons = tariff.sell_tariff?.seasons ?? tariff.seasons;
|
|
265
|
-
const sellSchedule = tariff.sell_tariff ? scheduleAt(sellSeasons, wallClock) : null;
|
|
266
|
-
const buyRate = { price: lookupPrice(tariff.energy_charges, buySchedule.seasonName, buySchedule.current.periodName), periodName: buySchedule.current.periodName, seasonName: buySchedule.seasonName };
|
|
267
|
-
const sellRate = sellSchedule?.current
|
|
268
|
-
? { price: lookupPrice(tariff.sell_tariff.energy_charges, sellSchedule.seasonName, sellSchedule.current.periodName), periodName: sellSchedule.current.periodName, seasonName: sellSchedule.seasonName }
|
|
269
|
-
: EMPTY_RATE;
|
|
270
|
-
// Boundaries are wall-clock minute deltas, so converting one back to an instant means
|
|
271
|
-
// re-deriving the target wall-clock label and reconverting *that*, not adding elapsed
|
|
272
|
-
// real minutes to `now` - the two differ across a DST transition.
|
|
273
|
-
const toDate = (gm) => {
|
|
274
|
-
const target = wallClockAt(wallClock, gm);
|
|
275
|
-
const hour = Math.floor(target.minuteOfDay / 60);
|
|
276
|
-
const minute = target.minuteOfDay % 60;
|
|
277
|
-
return new Date(wallClockToUtcMillis(target.year, target.month, target.day, hour, minute, timeZone));
|
|
278
|
-
};
|
|
279
|
-
// `scheduleAt` reports a next-boundary GM even for a grid that's currently in a gap (e.g. a
|
|
280
|
-
// sell/export window not open yet), so combining via the sell side's own next boundary - not
|
|
281
|
-
// skipping it just because sell has no active period right now - catches "sell starts" too.
|
|
282
|
-
const nextChangeGM = sellSchedule?.nextChangeGM != null ? Math.min(buySchedule.nextChangeGM, sellSchedule.nextChangeGM) : buySchedule.nextChangeGM;
|
|
283
|
-
// When buy and sell schedules differ, the interval the returned pair is valid for only began
|
|
284
|
-
// once BOTH sides' current *states* began - the later of the two, not just buy's. `sinceGM`
|
|
285
|
-
// covers sell being in a gap too (e.g. an export window that already closed), not only sell
|
|
286
|
-
// having its own active period. `buySchedule.sinceGM` is always non-null: buy is guaranteed to
|
|
287
|
-
// have an active `current` period at this point (checked above), and that branch always sets it.
|
|
288
|
-
const currentStartGM = sellSchedule?.sinceGM != null ? Math.max(buySchedule.sinceGM, sellSchedule.sinceGM) : buySchedule.sinceGM;
|
|
289
|
-
const resolution = {
|
|
290
|
-
buy: buyRate,
|
|
291
|
-
sell: sellRate,
|
|
292
|
-
currentStart: toDate(currentStartGM),
|
|
293
|
-
nextChange: toDate(nextChangeGM),
|
|
294
|
-
currency: typeof tariff.currency === "string" ? tariff.currency : null,
|
|
295
|
-
upcoming: null,
|
|
296
|
-
};
|
|
297
|
-
if (opts.horizonHours) {
|
|
298
|
-
resolution.upcoming = buildUpcoming(tariff.seasons, tariff.energy_charges, sellSeasons, tariff.sell_tariff?.energy_charges, !!tariff.sell_tariff, wallClock, opts.horizonHours * 60, toDate);
|
|
299
|
-
}
|
|
300
|
-
return resolution;
|
|
301
|
-
}
|
|
302
|
-
//# sourceMappingURL=tariff.js.map
|
package/dist/tariff.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tariff.js","sourceRoot":"","sources":["../src/tariff.ts"],"names":[],"mappings":"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"}
|