Add homebridge-tessie: rehome the Tessie Homebridge plugin from the legacy repo - #127
Add homebridge-tessie: rehome the Tessie Homebridge plugin from the legacy repo#127Bre77 wants to merge 2 commits into
Conversation
Rehomes the Tessie Homebridge plugin (fka Teslemetry/homebridge#tessie branch, hand-published) into this monorepo as packages/homebridge-tessie, matching homebridge-teslemetry's build/publish conventions. It talks to the Tessie backend via tesla-fleet-api directly, not @teslemetry/api, since the two services are unrelated backends. Fixes two NodeNext-resolution import extensions and one strict-mode implicit-any that the legacy repo's looser tsconfig let through.
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 6243d0c171
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| this.TeslaFleetApi = new Tessie(this.config.accessToken); | ||
|
|
||
| this.log.debug("Finished initializing platform:", this.config.accessToken); |
There was a problem hiding this comment.
Stop logging the Tessie access token
Whenever Homebridge runs with debug logging enabled, this writes the full Tessie access token into its logs and any collected diagnostics. Because the token grants access to vehicle and energy-site APIs, log only a non-sensitive initialization message.
Useful? React with 👍 / 👎.
| if ( | ||
| this.config?.ignore_site?.includes(product.asset_site_id) |
There was a problem hiding this comment.
Compare ignored sites against the numeric site ID
When a user supplies an ignore_site value, config.schema.json requires a number, but this compares it with asset_site_id, which is a string; the comparison therefore never matches and the site is still exposed. The numeric identifier used elsewhere for the site's context and API calls is energy_site_id.
Useful? React with 👍 / 👎.
| if (this.config?.ignore_vin?.includes(product.vin)) { | ||
| this.log.info("Ignoring vehicle", product.vin); | ||
| return; |
There was a problem hiding this comment.
Unregister accessories that become ignored
When a previously discovered vehicle is later added to ignore_vin, Homebridge restores its cached accessory before discovery and this early return merely skips reinitializing it; nothing in this package calls unregisterPlatformAccessories. The stale vehicle consequently remains visible in HomeKit indefinitely, without refresh handlers. Discovery should reconcile and unregister cached accessories that are now ignored or absent.
Useful? React with 👍 / 👎.
| // Create services | ||
| if (this.accessory.context.battery && this.accessory.context.grid && this.accessory.context.solar) { |
There was a problem hiding this comment.
Instantiate the energy battery service
For every energy site with a battery, this initialization path creates only control services and never constructs the supplied energy-services/battery.ts class. Since that class is the sole subscriber that publishes BatteryLevel, ChargingState, and StatusLowBattery, Powerwall users receive no HomeKit battery-status service.
Useful? React with 👍 / 👎.
| if (typeof data.components.disallow_charge_from_grid_with_solar_installed === "boolean") { | ||
| on.updateValue(data.components.disallow_charge_from_grid_with_solar_installed); |
There was a problem hiding this comment.
Invert the grid-charging state read from site info
For solar-and-battery sites, disallow_charge_from_grid_with_solar_installed is the inverse of the switch's “Charge From Grid” meaning, as the setter on line 13 already reflects. Updating On directly from this field reports enabled charging as off and prohibited charging as on after every refresh; use the negated value.
Useful? React with 👍 / 👎.
| .onSet(async (value) => { | ||
| if (value) { |
There was a problem hiding this comment.
Trigger Homelink for the open target state
When a user asks the garage-door accessory to open, HomeKit supplies TargetDoorState.OPEN (numeric value 0), so this truthiness guard skips trigger_homelink. Conversely, requesting the CLOSED value (1) triggers the command, leaving the accessory's primary open action nonfunctional.
Useful? React with 👍 / 👎.
| this.parent.emitter.on("vehicle_data", (data) => { | ||
| const state = (data.charge_state.charge_port_latch === "Engaged") ? 1 : 0; |
There was a problem hiding this comment.
Derive charge-port state from the door sensor
When the charge-port door is closed with no cable attached, its latch is disengaged, so this reports the lock as unsecured even though the service maps secured/unsecured to closed/open. It also reports secured while a cable is latched through an open door. Use charge_port_door_open rather than the cable-latch state.
Useful? React with 👍 / 👎.
- Stop logging the raw Tessie access token at debug level; log the platform name instead. - Compare ignore_site against the numeric energy_site_id (matching config.schema.json's number type and the ID used elsewhere), not the string asset_site_id, which never matched. - Unregister cached accessories that are no longer discovered or have become ignored, instead of leaving them stuck in HomeKit. - Instantiate the energy BatteryService, which existed but was never constructed, so Powerwall sites get a HomeKit battery status. - Un-invert the site_info refresh path for the "Charge From Grid" switch to match the onSet handler's existing inversion. - Fix the Homelink garage-door trigger to fire on the OPEN target state (0) instead of CLOSED (1). - Derive the charge port lock state from charge_port_door_open rather than the cable-latch state, which produced wrong results whenever the door was closed with no cable connected.
|
Superseded — the Tessie plugin is getting its own repo instead (it doesn't use the Teslemetry SDK, and this monorepo's unifying thread is that SDK): https://github.com/Teslemetry/homebridge-tessie |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0600f1d532
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| { | ||
| "name": "homebridge-tessie", | ||
| "displayName": "Tessie", | ||
| "version": "0.4.4", |
There was a problem hiding this comment.
Add a changeset for the migrated package
Because this same-name migration retains the already-published 0.4.4 version and adds no changeset naming homebridge-tessie, the changesets action has no pending version bump for the package and will skip publishing the repository build. Add a patch changeset so the Version Packages PR advances the package beyond the legacy release.
AGENTS.md reference: AGENTS.md:L198-L198
Useful? React with 👍 / 👎.
| current.updateValue(false); | ||
| target.updateValue(false); |
There was a problem hiding this comment.
Reset Homelink to the closed state after triggering
After the new OPEN-path fix, a successful trigger writes false to both characteristics, but false is numeric 0, which is the HomeKit OPEN state. The accessory therefore remains displayed as open, and because this handler only triggers when the target is changed to OPEN, the user must first issue an ignored CLOSED request before Homelink can be triggered again; reset both characteristics to their CLOSED enum values after the momentary command.
Useful? React with 👍 / 👎.
| "platform": "Tessie", | ||
| "name": "My Tessie", | ||
| "accessToken": "YOUR_TESSIE_TOKEN", | ||
| "prefixName": true, |
There was a problem hiding this comment.
Intent
Teslemetry/homebridge(tessiebranch, hand-published viapublish.sh) since before this monorepo existed, as a stopgap untilhomebridge-teslemetrypublished from here. That repo is being archived, and the captain decided (2026-08-17) the Tessie plugin lives on — it needs a home before then.packages/homebridge-tessie, a fresh import of thetessiebranch'ssrc/,README.md,LICENSE, andconfig.schema.json, structured and built exactly likehomebridge-teslemetry(tsdown,tsc --noEmit,tsx --test, oxlint, changesets).tesla-fleet-apidirectly, not@teslemetry/api— Tessie is a different backend from Teslemetry, so there's nothing to share with the SDK the other integration packages use.NodeNext-resolution import extensions and one strict-mode implicit-anythat the legacy repo's loosertsconfig/noImplicitAny: falselet through; no behavior changes otherwise.VehicleService.ts— dead code, nothing imported it.publish.ymlflow with zero workflow changes —homebridge-tessieneeds npm trusted publishing registered for the package name before the release job'schangeset publishcan succeed, same requirementhomebridge-teslemetryalready has. That's an npm org-owner action outside this PR's scope, mirroring the ioBroker submission's outward-facing-permission carve-out.Teslemetry/homebridge. Both are separate, later steps once this package is proven.Full narrative / original brief
Phase 1 scoping conclusion: the "monorepo plugin" the legacy repo was a stopgap for is this repo (
Teslemetry/typescript-teslemetry), which already containspackages/homebridge-teslemetryas the current home for the Teslemetry plugin, publishing via changesets + npm trusted publishing on merge tomain. Since this is an existing repo we control, no new public repo was needed and the HARD GATE in the brief did not trigger — proceeding straight to migration.