Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/bundle-tariff-periods-helper.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@teslemetry/api": minor
---

Adds `getTariffPeriods` and the `TariffContentV2` type it consumes, re-exported from the package root. The implementation is bundled in from `tesla-fleet-api` at build time (a devDependency, inlined by tsdown) - consumers get tariff resolution without taking a runtime dependency on `tesla-fleet-api` themselves.
2 changes: 2 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ See each package's own `package.json`/`README.md` for its purpose and structure
- The `input:` in `openapi-ts.config.ts` fetches the live `api.teslemetry.com/openapi.yaml`, not the api repo's committed `openapi.json` directly - the two can briefly diverge around a deploy, and empirically the live endpoint can even be *ahead* of the api repo's committed snapshot file (which isn't necessarily regenerated on every commit). If regenerating to pick up a specific just-merged api-repo change, prefer fetching that repo's `openapi.json` from its `main` branch over trusting the live endpoint's current deploy state.
- CI (`.github/workflows/ci.yml`, "Verify API client codegen toolchain" step) regenerates into a throwaway temp directory on every PR specifically to catch a toolchain break like this one at PR time - it does not diff against the committed `src/client/`, since the live spec drifting is expected and not itself a bug.

**Gotcha**: `getTariffPeriods`/`TariffContentV2` (`src/tariff.ts`) are bundled in from the published `tesla-fleet-api` npm package rather than hand-ported - tsdown externalizes `dependencies`/`peerDependencies` by default but bundles `devDependencies`, so `tesla-fleet-api` is a `devDependency` here specifically to get inlined into `dist/` with no runtime dependency on it. `src/tariff.ts` deep-imports `tesla-fleet-api/dist/tariff.js` and `tesla-fleet-api/dist/types/site_info.js` directly (not the package root) so tree-shaking never has to prove the rest of that package's vehicle/signing/commands surface is side-effect-free - importing the root would risk dragging all of it in. `tsdown.config.ts`'s `deps.onlyBundle: ["tesla-fleet-api"]` documents that inlining as intentional (silences tsdown's unintentional-bundling hint); adding another bundled devDependency needs a matching entry there.

### 2. `node-red-contrib-teslemetry` - Node-RED Integration

**Location**: `packages/node-red-contrib-teslemetry/`
Expand Down
16 changes: 16 additions & 0 deletions packages/api/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,22 @@ REST `site_info` response:
const document = site.sse.siteInfoDocument; // undefined until site_info is cached
```

`getTariffPeriods` resolves the current buy/sell rate (and, optionally, the
upcoming schedule) from a `tariff_content_v2` body - pass the site's IANA
`installation_time_zone`, since the tariff itself carries no timezone:

```typescript
import { getTariffPeriods, type TariffContentV2 } from "@teslemetry/api";

const tariff = document?.tariff_content_v2 as TariffContentV2 | null;
if (tariff) {
const resolution = getTariffPeriods(tariff, new Date(), {
timeZone: document.installation_time_zone,
});
console.log(resolution?.buy.price);
}
```

### Energy API

Interact with Tesla Energy sites (Solar, Powerwall, Wall Connector).
Expand Down
1 change: 1 addition & 0 deletions packages/api/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
"devDependencies": {
"@hey-api/openapi-ts": "0.0.0-next-20260728215008",
"dotenv": "^17.2.3",
"tesla-fleet-api": "^0.2.2",
"tsdown": "^0.22.4",
"tsx": "^4.20.6"
}
Expand Down
7 changes: 7 additions & 0 deletions packages/api/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,10 @@ export * from "./const.js";
export * from "./sseTopics.js";
export * from "./exceptions.js";
export type { EnergyDetails, VehicleDetails, Products } from "./const.js";
export { getTariffPeriods } from "./tariff.js";
export type {
TariffContentV2,
TariffRate,
TariffPeriod,
TariffResolution,
} from "./tariff.js";
11 changes: 11 additions & 0 deletions packages/api/src/tariff.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
// Bundled from `tesla-fleet-api` at build time (devDependency, inlined by tsdown) so
// consumers get tariff resolution without a runtime dependency on that package. Deep-imported
// from its own submodules rather than the package root to keep tree-shaking narrow to this
// helper's closure, not tesla-fleet-api's vehicle/energy/signing surface.
export { getTariffPeriods } from "tesla-fleet-api/dist/tariff.js";
export type {
TariffRate,
TariffPeriod,
TariffResolution,
} from "tesla-fleet-api/dist/tariff.js";
export type { TariffContentV2 } from "tesla-fleet-api/dist/types/site_info.js";
9 changes: 9 additions & 0 deletions packages/api/tsdown.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { defineConfig } from "tsdown";

export default defineConfig({
deps: {
// tesla-fleet-api's getTariffPeriods is bundled in from a devDependency (see src/tariff.ts)
// so @teslemetry/api carries no runtime dependency on it - declare that intentional.
onlyBundle: ["tesla-fleet-api"],
},
});
23 changes: 23 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading