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
37 changes: 21 additions & 16 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,15 @@ All notable changes are listed here. `Unreleased` is what `main` and the Docker

## Unreleased

### Breaking
## 2.5.0 - 2026-10-19

- `/gen_keys` and `/remove_keys` accept `POST` only. `GET` now returns `405`. The dashboard already uses `POST`; scripts or bookmarks that call these endpoints with `GET` must switch. ([#170](https://github.com/wimaha/TeslaBleHttpProxy/pull/170))
- Possibly breaking for integrations: requests that fail are now always reported as failures (`result: false`, HTTP 503). Before, some of them, for example `set_charging_amps` without a body, returned `result: true` without doing anything. Commands sent without `wait=true` that cannot be queued (queue full, key change) now return 503 instead of "will be processed shortly". `body_controller_state` waits in the command queue and answers with an error after 15 seconds if the proxy is busy, for example retrying while the car is out of range. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
### Upgrade notes

Normal setups with evcc or Home Assistant are not affected and need no changes. The points below only matter in the cases they name.

- If you open the dashboard through a reverse proxy over plain HTTP that rewrites the `Host` header, its buttons now answer `403`. Set [`trustedOrigins`](docs/environment_variables.md#trustedorigins) to the address you open in the browser. Over HTTPS nothing needs to be set. ([#170](https://github.com/wimaha/TeslaBleHttpProxy/pull/170))
- `/gen_keys` and `/remove_keys` accept `POST` only. `GET` now returns `405`. The dashboard already uses `POST`; only scripts or bookmarks that called these undocumented endpoints with `GET` must switch. ([#170](https://github.com/wimaha/TeslaBleHttpProxy/pull/170))
- Requests that fail are now always reported as failures (`result: false`, HTTP 503). Before, some of them, for example `set_charging_amps` without a body, returned `result: true` without doing anything. Commands sent without `wait=true` that cannot be queued (queue full, key change) now return 503 instead of "will be processed shortly". `body_controller_state` waits in the command queue and answers with an error after 15 seconds if the proxy is busy, for example retrying while the car is out of range. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))

### Security

Expand All @@ -16,29 +21,29 @@ All notable changes are listed here. `Unreleased` is what `main` and the Docker

### Added

- Vehicle status on the dashboard: connection and sleep state, battery and charging, climate, lock state, last contact and last error per vehicle, each with the time its data is from. It updates itself every 10 seconds from what the proxy already knows and never contacts the vehicle on its own; **Refresh** fetches current data without waking it, **Wake & refresh** wakes it first. New endpoints `GET /api/proxy/1/status` and `POST /api/proxy/1/status/refresh`. ([#168](https://github.com/wimaha/TeslaBleHttpProxy/issues/168))
- Vehicle status on the dashboard: connection and sleep state, battery and charging, climate, lock state, last contact and last error per vehicle, each with the time its data is from. It updates itself every 10 seconds from what the proxy already knows and never contacts the vehicle on its own; **Refresh** fetches current data without waking it, **Wake & refresh** wakes it first. New endpoints `GET /api/proxy/1/status` and `POST /api/proxy/1/status/refresh`. ([#168](https://github.com/wimaha/TeslaBleHttpProxy/issues/168), [#176](https://github.com/wimaha/TeslaBleHttpProxy/pull/176))
- `trustedOrigins` environment variable for reverse proxies over plain HTTP that rewrite the `Host` header, and for web pages on other origins that call the API. See [environment variables](docs/environment_variables.md#trustedorigins). ([#170](https://github.com/wimaha/TeslaBleHttpProxy/pull/170))
- Docker image `:dev`, built from `main` on every push. ([#171](https://github.com/wimaha/TeslaBleHttpProxy/pull/171))
- Docker image `:pr-<number>` for every pull request from a branch of this repository, to test a change on a car before it is merged. See [Test images for pull requests](README.md#test-images-for-pull-requests).
- `releaseAdapterWhenIdle` environment variable: hands the Bluetooth adapter back to the system between connections, so other Bluetooth services on the same host can use it. Off by default. Fixes [#158](https://github.com/wimaha/TeslaBleHttpProxy/issues/158), based on [#161](https://github.com/wimaha/TeslaBleHttpProxy/pull/161) by @AloisKlingler.
- `connectionTimeout` environment variable: how long a connection stays open after a command (default 29 seconds as before). Based on [#161](https://github.com/wimaha/TeslaBleHttpProxy/pull/161) by @AloisKlingler.
- Docker image `:pr-<number>` for every pull request from a branch of this repository, to test a change on a car before it is merged. See [Test images for pull requests](README.md#test-images-for-pull-requests). ([#175](https://github.com/wimaha/TeslaBleHttpProxy/pull/175))
- `releaseAdapterWhenIdle` environment variable: hands the Bluetooth adapter back to the system between connections, so other Bluetooth services on the same host can use it. Off by default. Fixes [#158](https://github.com/wimaha/TeslaBleHttpProxy/issues/158), based on [#161](https://github.com/wimaha/TeslaBleHttpProxy/pull/161) by @AloisKlingler. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- `connectionTimeout` environment variable: how long a connection stays open after a command (default 29 seconds as before). Based on [#161](https://github.com/wimaha/TeslaBleHttpProxy/pull/161) by @AloisKlingler. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- README examples for `set_charge_limit` and `set_sentry_mode`. ([#169](https://github.com/wimaha/TeslaBleHttpProxy/pull/169))

### Fixed

- `set_charging_amps`, `set_charge_limit` and `set_sentry_mode` with a missing or invalid body answer with an error before the car is contacted. Before, they could report success without doing anything. Other errors that are not retried are reported too instead of coming back as success.
- `body_controller_state` goes through the command queue: it no longer opens a second Bluetooth connection next to a running command, and it is answered right away on an open connection.
- Changing or generating keys in the dashboard stops the previous command loop instead of leaving it running next to the new one. Requests during the change get a clear error instead of hanging.
- `set_charging_amps`, `set_charge_limit` and `set_sentry_mode` with a missing or invalid body answer with an error before the car is contacted. Before, they could report success without doing anything. Other errors that are not retried are reported too instead of coming back as success. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- `body_controller_state` goes through the command queue: it no longer opens a second Bluetooth connection next to a running command, and it is answered right away on an open connection. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- Changing or generating keys in the dashboard stops the previous command loop instead of leaving it running next to the new one. Requests during the change get a clear error instead of hanging. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- A client that disconnects while a response is written no longer stops the proxy. ([#170](https://github.com/wimaha/TeslaBleHttpProxy/pull/170))

### Changed

- `body_controller_state` waits in the command queue like every other request. If the proxy is busy with another command or retrying a connection, it answers with an error after at most 15 seconds instead of opening a second connection. A caller that gave up is not sent to the vehicle later.
- Errors are reported more strictly: requests that failed without being retried (for example a missing body) now return `result: false` (HTTP 503), where some used to return `result: true`.
- When the command queue is full (50 waiting requests, the vehicle has been unreachable for a while), new requests are answered with an error right away instead of waiting.
- Sending a key to the vehicle from the dashboard closes an idle connection of the command loop first and waits at most 30 seconds for a busy one.
- Updated BLE library ([wimaha/ble_BleConnectFix#1](https://github.com/wimaha/ble_BleConnectFix/pull/1)): when the proxy closes the adapter, it is brought back up, so BlueZ sees it again. Needed for `releaseAdapterWhenIdle`.
- Building from source requires Go 1.27 or newer; the Docker image is built with Go 1.27.2. ([#172](https://github.com/wimaha/TeslaBleHttpProxy/pull/172))
- `body_controller_state` waits in the command queue like every other request. If the proxy is busy with another command or retrying a connection, it answers with an error after at most 15 seconds instead of opening a second connection. A caller that gave up is not sent to the vehicle later. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- Errors are reported more strictly: requests that failed without being retried (for example a missing body) now return `result: false` (HTTP 503), where some used to return `result: true`. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- When the command queue is full (50 waiting requests, the vehicle has been unreachable for a while), new requests are answered with an error right away instead of waiting. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- Sending a key to the vehicle from the dashboard closes an idle connection of the command loop first and waits at most 30 seconds for a busy one. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- Updated BLE library ([wimaha/ble_BleConnectFix#1](https://github.com/wimaha/ble_BleConnectFix/pull/1)): when the proxy closes the adapter, it is brought back up, so BlueZ sees it again. Needed for `releaseAdapterWhenIdle`. ([#174](https://github.com/wimaha/TeslaBleHttpProxy/pull/174))
- Building from source requires Go 1.27 or newer; the Docker image is built with Go 1.27.2. ([#172](https://github.com/wimaha/TeslaBleHttpProxy/pull/172), [#178](https://github.com/wimaha/TeslaBleHttpProxy/pull/178))
- Tests run against a simulated vehicle, so commands, connection handling and the HTTP API are covered without a car. ([#169](https://github.com/wimaha/TeslaBleHttpProxy/pull/169))

## 2.4.0 - 2026-10-17
Expand Down
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# TeslaBleHttpProxy

> **Note:** This README describes the current development state (`main`, Docker `:dev`). For the latest release **2.4.0** (Docker `:latest`) see the [README of 2.4.0](https://github.com/wimaha/TeslaBleHttpProxy/blob/2.4.0/README.md). What changed since then is listed in the [CHANGELOG](CHANGELOG.md). Sections marked *(unreleased)* are only in `:dev`.
> **Note:** This README describes the current development state (`main`, Docker `:dev`). For the latest release **2.5.0** (Docker `:latest`) see the [README of 2.5.0](https://github.com/wimaha/TeslaBleHttpProxy/blob/2.5.0/README.md). What changed since then is listed in the [CHANGELOG](CHANGELOG.md). Sections marked *(unreleased)* are only in `:dev`.

TeslaBleHttpProxy is a program written in Go that receives HTTP requests and forwards them via Bluetooth to a Tesla vehicle. The program can, for example, be easily used together with [evcc](https://github.com/evcc-io/evcc).

Expand Down Expand Up @@ -244,7 +244,7 @@ This is recommended if you want to receive data frequently, since it will reduce

The body controller state is fetched from the vehicle and returnes the state of the body controller. The request does not wake up the vehicle. The following information is returned:

*(unreleased)*
*(since 2.5.0)*

The request goes through the same queue as commands, so there is only ever one Bluetooth connection to the vehicle. If a connection is already open, it is answered on it right away. If the proxy is busy with another command (for example retrying while the vehicle is out of range), the request waits for at most 15 seconds and then answers with an error.

Expand Down Expand Up @@ -278,7 +278,7 @@ The response will contain the version of the proxy.

### Status of Proxy and Vehicles

*(unreleased)*
*(since 2.5.0)*

The dashboard (`http://localhost:8080/dashboard`) shows the status of the proxy and of each vehicle it has talked to: connection, sleep state, battery and charging, climate, lock state, and the last successful contact and last error. Every block shows when its data was fetched. Opening or auto-updating the dashboard never contacts the vehicle; it only shows what the proxy already knows, for example from evcc polling `vehicle_data`. **Refresh** fetches current data without waking the vehicle; **Wake & refresh** wakes it first (after a confirmation).

Expand Down Expand Up @@ -312,13 +312,13 @@ This is a Tesla vehicle constraint, not a limitation of TeslaBleHttpProxy.

### Sharing the Bluetooth adapter with other services

*(unreleased)*
*(since 2.5.0)*

By default the proxy keeps the Bluetooth adapter for itself while it runs, so other Bluetooth services on the same host (for example a door lock using BlueZ) report "No Bluetooth adapters found". Set [`releaseAdapterWhenIdle=true`](docs/environment_variables.md#releaseadapterwhenidle) to hand the adapter back whenever no connection to the car is open, and a lower [`connectionTimeout`](docs/environment_variables.md#connectiontimeout) such as `10` to free it sooner after a command.

### Dashboard buttons return 403 Forbidden

*(unreleased)*
*(since 2.5.0)*

The proxy rejects state-changing requests that a browser sends from another website, so a page you visit cannot change your keys or send commands to the car. If you open the dashboard through a reverse proxy over plain HTTP that rewrites the `Host` header, your own requests can look cross-site too. Set the [`trustedOrigins`](docs/environment_variables.md#trustedorigins) environment variable to the address you open in the browser, e.g. `trustedOrigins=http://nas.local:8080`. Over HTTPS this is not needed.

Expand Down
6 changes: 3 additions & 3 deletions docs/environment_variables.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ This is the address and port to listen for HTTP requests. (Default: :8080)

## trustedOrigins

*(unreleased)*
*(since 2.5.0)*

Comma-separated list of origins (`scheme://host[:port]`) that may send state-changing requests (dashboard buttons, commands) from a browser. Requests from evcc, curl or Home Assistant integrations are not affected. (Default: empty)

Expand All @@ -39,13 +39,13 @@ Case, a trailing slash and the default ports `:80`/`:443` do not matter. Several

## connectionTimeout

*(unreleased)*
*(since 2.5.0)*

The number of seconds a Bluetooth connection to the vehicle stays open after a command, so that further commands (for example from evcc) are sent without connecting again. A lower value frees the Bluetooth adapter sooner, which matters with `releaseAdapterWhenIdle`; a higher value means fewer reconnects. (Default: 29)

## releaseAdapterWhenIdle

*(unreleased)*
*(since 2.5.0)*

If `true`, the proxy hands the Bluetooth adapter back to the system (BlueZ) whenever no connection to the vehicle is open, so other Bluetooth services on the same host can use it, for example a door lock. By default the proxy keeps the adapter for itself until it stops. With this option every new connection sets up the adapter again, which takes a little longer. Combine it with a lower `connectionTimeout` (for example `10`) to free the adapter sooner after a command. (Default: false)

Expand Down
Loading