# Technical Documentation: teslamate-org/teslamate

> ℹ️ **Provenance:** Multi-Tier Ingestion · [CodeWiki Reference](https://codewiki.google/github.com/teslamate-org/teslamate)

### Overview (`README.md`)

# TeslaMate

[](https://github.com/teslamate-org/teslamate/blob/main/NOTICE)
[](https://www.bestpractices.dev/projects/10859)
[](https://github.com/teslamate-org/teslamate/actions/workflows/devops.yml)
[](https://github.com/teslamate-org/teslamate/actions/workflows/buildx.yml)
[](https://coveralls.io/github/teslamate-org/teslamate?branch=main)
[](https://hub.docker.com/r/teslamate/teslamate)
[](https://hub.docker.com/r/teslamate/teslamate)
[](https://hub.docker.com/r/teslamate/teslamate)

A powerful, self-hosted data logger for your Tesla.

- Written in **[Elixir](https://elixir-lang.org/)**
- Data is stored in a **Postgres** database
- Visualization and data analysis with **Grafana**
- Vehicle data is published to a local **[MQTT](https://en.wikipedia.org/wiki/MQTT)** Broker

## ⚠️ Security Warning

> [!CAUTION]
> **Use Official Versions Only**

To protect yourself from malicious forks, malware, and data theft, please ensure you only obtain TeslaMate from the official source:

- Official Repository: [https://github.com/teslamate-org/teslamate](https://github.com/teslamate-org/teslamate)
- Official Documentation: [https://docs.teslamate.org](https://docs.teslamate.org/)

We have received reports of deceptive websites and unofficial mobile apps (e.g. on the App Store) using the TeslaMate name to distribute modified or harmful versions. If you are using a version from another source, your Tesla account credentials and vehicle data may be at risk.

## Documentation

The documentation is available at [https://docs.teslamate.org](https://docs.teslamate.org/)

## Features

### General

- High precision drive data recording
- No additional vampire drain: the car will fall asleep as soon as possible
- Automatic address lookup
- Easy integration into Home Assistant (via MQTT)
- Easy integration into Node-Red & Telegram (via MQTT)
- Geo-fencing feature to create custom locations
- Supports multiple vehicles per Tesla Account
- Charge cost tracking
- Import from TeslaFi and tesla-apiscraper
- Customizable theme mode (light, dark, or system default)
- Web interface in 19 languages (Catalan, Danish, Dutch, English, Finnish, French, German, Hungarian, Italian, Japanese, Korean, Norwegian Bokmål, Simplified Chinese, Spanish, Swedish, Thai, Traditional Chinese, Turkish, Ukrainian); untranslated text falls back to English

### Dashboards

Sample screenshots of bundled dashboards can be seen by clicking the links below.

- [Battery Health](https://docs.teslamate.org/docs/screenshots/#battery-health)
- [Charge Level](https://docs.teslamate.org/docs/screenshots/#charge-level)
- [Charges (Energy added / used)](https://docs.teslamate.org/docs/screenshots#charges)
- [Charge Details](https://docs.teslamate.org/docs/screenshots#charge-details)
- [Charging Stats](https://docs.teslamate.org/docs/screenshots#charging-stats)
- [Database Information](https://docs.teslamate.org/docs/screenshots/#database-information)
- [Drive Stats](https://docs.teslamate.org/docs/screenshots#drive-stats)
- [Drives (Distance / Energy consumed (net))](https://docs.teslamate.org/docs/screenshots/#drives)
- [Drive Details](https://docs.teslamate.org/docs/screenshots/#drive-details)
- [Efficiency (Consumption (net / gross))](https://docs.teslamate.org/docs/screenshots#efficiency)
- [Locations (addresses)](https://docs.teslamate.org/docs/screenshots/#location-addresses)
- [Mileage](https://docs.teslamate.org/docs/screenshots/#mileage)
- [Overview](https://docs.teslamate.org/docs/screenshots/#overview)
- [Projected Range (battery degradation)](https://docs.teslamate.org/docs/screenshots#projected-range)
- [States (see when your car was online or asleep)](https://docs.teslamate.org/docs/screenshots#states)
- [Statistics](https://docs.teslamate.org/docs/screenshots/#statistics)
- [Temperatures](https://docs.teslamate.org/docs/screenshots/#temperatures)
- [Timeline](https://docs.teslamate.org/docs/screenshots/#timeline)
- [Trip](https://docs.teslamate.org/docs/screenshots/#trip)
- [Updates (History of installed updates)](https://docs.teslamate.org/docs/screenshots#updates)
- [Vampire Drain](https://docs.teslamate.org/docs/screenshots#vampire-drain)
- [Visited (Lifetime driving map)](https://docs.teslamate.org/docs/screenshots/#visited-lifetime-driving-map)

## Screenshots

Sneak peak into TeslaMate interface and bundled dashboards. See [the docs](https://docs.teslamate.org/docs/screenshots) for additional screenshots.







## License

TeslaMate is licensed under the **GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)**. See [NOTICE](https://github.com/teslamate-org/teslamate/blob/main/NOTICE) for the copyright notice, the additional terms under section 7 of the AGPL, and the trademark notice. For the full legal terms, please refer to the [LICENSE](https://github.com/teslamate-org/teslamate/blob/main/LICENSE) file.

This license is designed to ensure that TeslaMate remains free and open for everyone and that improvements made by commercial entities or third parties remain open to the entire community. By using, modifying, or building upon this project, you agree to the following:

- Copyleft: If you modify TeslaMate or incorporate it into another project, you must release the entire source code of your version under the same license (AGPL-3.0-or-later). This applies regardless of how you provide the software to others, in any form, including, without limitation, as a downloadable application, a binary, a package, a pre-packaged image, or a network service (SaaS).
- No Closed-Source Derivatives: We do not permit the use of TeslaMate or its components in closed-source products. Any software made to work with TeslaMate, including, without limitation, apps, dashboards, integrations, and services, must be open-source under an AGPL-compatible license. Software that integrates with TeslaMate may do so only via the supported integration surface (MQTT). If you build upon this project, you are expected to contribute back to the community.
- Attribution: You must keep all original copyright notices, the NOTICE file, and license information intact, and clearly mark modified versions as modified.

**Trademark Policy**: The use of all trademarks of the TeslaMate project is governed by our [Trademark Policy](https://github.com/teslamate-org/teslamate/blob/main/TRADEMARK.md).

**Disclaimer:** TeslaMate is an independent project and is not affiliated with, endorsed by, or sponsored by Tesla, Inc. "Tesla" and related marks are trademarks of Tesla, Inc.

**Contributions:** All contributors must sign our [Fiduciary License Agreement (FLA 2.0)](https://github.com/teslamate-org/legal/blob/main/CLA.md). This is handled via cla-assistant.io automatically on first PR and does not take long. **Why do we need this?** It guarantees that TeslaMate will **always remain Free Software** and allows the [teslamate-org](https://github.com/teslamate-org) to legally defend the project against license violations.

## Popularity

[](https://trendshift.io/repositories/24134?utm_source=repository-badge&utm_medium=badge&utm_campaign=badge-repository-24134)


<a href="https://www.star-history.com/?repos=teslamate-org%2Fteslamate&type=date&legend=top-left">
 <picture>
   <source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/chart?repos=teslamate-org/teslamate&type=date&theme=dark&legend=top-left&sealed_token=fwiuAlNEUj8eYQn1rfDBWuO1X-8D__oKgCwEMpguLFI2sKX84ySGDr-ZyaTvrmyCVFq6FMq3S9tbx08hNAB0n7zSsvxhhy12ywx2HW3RImbgY6xKsBIcDS0TeHVg9eReGL2CPHWQkQ8DWva51A5f-SCzPaoknJ3R82Vvm813x8wPAQIeuTurVEG5VnSw" />
   <source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/chart?repos=teslamate-org/teslamate&type=date&legend=top-left&sealed_token=fwiuAlNEUj8eYQn1rfDBWuO1X-8D__oKgCwEMpguLFI2sKX84ySGDr-ZyaTvrmyCVFq6FMq3S9tbx08hNAB0n7zSsvxhhy12ywx2HW3RImbgY6xKsBIcDS0TeHVg9eReGL2CPHWQkQ8DWva51A5f-SCzPaoknJ3R82Vvm813x8wPAQIeuTurVEG5VnSw" />
   <img alt="Star History Chart" src="https://api.star-history.com/chart?repos=teslamate-org/teslamate&type=date&legend=top-left&sealed_token=fwiuAlNEUj8eYQn1rfDBWuO1X-8D__oKgCwEMpguLFI2sKX84ySGDr-ZyaTvrmyCVFq6FMq3S9tbx08hNAB0n7zSsvxhhy12ywx2HW3RImbgY6xKsBIcDS0TeHVg9eReGL2CPHWQkQ8DWva51A5f-SCzPaoknJ3R82Vvm813x8wPAQIeuTurVEG5VnSw" />
 </picture>
</a>


## Credits

- Initial Author: Adrian Kumpf
- List of Contributors:
- [](https://github.com/teslamate-org/teslamate/graphs/contributors)

---

### Overview (`website/README.md`)

# Website

This website is built using [Docusaurus 2](https://v2.docusaurus.io/), a modern static website generator and automatically deployed to [docs.teslamate.org](https://docs.teslamate.org).

## Installation

```console
npm i
```

### Local Development

```console
npm start
```

This command starts a local development server and open up a browser window. Most changes are reflected live without having to restart the server.

### Build

```console
npm run build
```

This command generates static content into the `build` directory and can be served using any static contents hosting service.

### Deployment

```console
GIT_USER=<Your GitHub username> USE_SSH=true npm run deploy
```

If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.

---

### Development (`website/docs/development.mdx`)

---
id: development
title: Development and Contributing
sidebar_label: Development and Contributing
---

## Requirements

TeslaMate officially supports the versions listed below. In general, TeslaMate aims to stay compatible with the last three major Erlang and Postgres releases and the last three minor Elixir releases. At the moment, OTP 28+ is a hard requirement, so Elixir support is currently limited to versions that support OTP 28+ (Elixir v1.19 and v1.20).
When contributing, please use the versions listed below, which match those used in official TeslaMate distributions.

- **Elixir** >= 1.20.3-otp-29
- **Postgres** >= 18.0
- **Grafana** = 13.2.3
- An **MQTT broker** e.g. mosquitto (_optional_)
- **NodeJS** >= 22.22.0

or [Nix](https://nixos.org/download/). You can then use the nix devenv (via direnv) setup.

## Initial Setup

The Elixir application lives in `elixir/`; all `mix` commands on this page run from that directory.

To run the TeslaMate test suite you need a database named `teslamate_test`:

```bash
# download dependencies, create the dev database and run migrations
mix setup

# create the test database
MIX_ENV=test mix ecto.setup
```

## Running locally

Start an iex session in another terminal window:

```elixir
iex -S mix phx.server
```

Then sign in with a Tesla account.

## Hot reloading

To immediately apply your local changes open or reload [http://localhost:4000](http://localhost:4000). You can also reload specific modules via `iex`, for example:

```elixir
iex> r TeslaMate.Vehicles.Vehicle
```

To only compile the changes:

```bash
mix compile
```

## Code formatting

### Format all files

Install [Treefmt](https://github.com/numtide/treefmt/releases) or use nix develop or the nix devenv (via direnv) setup.

```bash
treefmt
```

or with nix flake app, when not using direnv:

```bash
nix run .#lint
```

You can even use a VS Code extension like [treefmt](https://marketplace.visualstudio.com/items?itemName=ibecker.treefmt-vscode) to format the files on save.

### Only format elixir files

```bash
mix format
```

## Update pot files (extract messages for translation)

```bash
mix gettext.extract --merge
```

## Testing

To ensure a commit passes CI you should run `mix ci` locally, which executes the following commands:

- Check formatting (`mix format --check-formatted`)
- Check for unused dependencies (`mix deps.unlock --check-unused`)
- Run all tests (`mix test --raise`)

### Testing with our CI which builds the Docker images automatically per PR

Our CI automatically builds the Docker images for each PR (only for repo own PRs, not for external PRs). To test the changes introduce by a PR you can edit your docker-compose.yml file as follows (replace `pr-3836` with the PR number):

For TeslaMate:

```yml
teslamate:
  # image: teslamate/teslamate:latest
  image: ghcr.io/teslamate-org/teslamate:pr-3836
```

For Grafana:

```yml
grafana:
  # image: teslamate/grafana:latest
  image: ghcr.io/teslamate-org/teslamate/grafana:pr-3836
```

## Making Changes to Grafana Dashboards

Use **`teslamate/grafana:edge`** for local dashboard work. Export JSON as Grafana saves it into `./grafana/dashboards/`.

```yml
services:
  grafana:
    image: teslamate/grafana:edge
    environment:
      - DATABASE_USER=postgres
      - DATABASE_PASS=postgres
      - DATABASE_NAME=teslamate_dev
      - DATABASE_HOST=host.docker.internal
    ports:
      - 3000:3000
    volumes:
      - grafana-data:/var/lib/grafana

volumes:
  grafana-data:
```

_(on Linux use the actual IP address of the host as `DATABASE_HOST` instead of `host.docker.internal`)_

```bash
docker compose up grafana
```

Open [http://localhost:3000](http://localhost:3000) (`admin` / `admin`), edit the dashboard, then **Export** → **Export as code**. Under **Advanced options**, set **Model** to **Classic** (not **V2 Resource**), then **Download file** into `./grafana/dashboards/`.

When making larger changes to Grafana Dashboards please include updated screenshots (1920x1080 @ x2, Grafana running in Kiosk mode) in `./website/static/screenshots`. Ensure to blur sensitive information.

## Best Practices

### Dashboard variables and units

Most dashboards follow a shared shell. Prefer copying variable and link blocks from a similar existing dashboard (e.g. Overview or Efficiency) rather than inventing new shapes.

Common template variables:

| Variable          | Typical source                 | When                     |
| ----------------- | ------------------------------ | ------------------------ |
| `car_id`          | `cars`                         | Almost always            |
| `base_url`        | `settings.base_url`            | Header link to TeslaMate |
| `length_unit`     | `settings.unit_of_length`      | Distance / speed         |
| `temp_unit`       | `settings.unit_of_temperature` | Temperature              |
| `preferred_range` | `settings.preferred_range`     | Ideal vs rated range     |

Typical header links: **TeslaMate** → `${base_url:raw}`, plus a **Dashboards** dropdown on tag `tesla`.

Use the database helpers so user settings apply:

- Temperature: `convert_celsius(column, '$temp_unit')` — do not hardcode Celsius-only units, axis labels, or thresholds when `temp_unit` exists
- Distance / speed: `convert_km(column, '$length_unit')`

### Queries involving timestamp columns

Datetime values are currently stored in columns of type `timestamp`. [This is NOT recommended](https://wiki.postgresql.org/wiki/Don't_Do_This#Don.27t_use_timestamp_.28without_time_zone.29_to_store_UTC_times).

While [Grafana macros](https://grafana.com/docs/grafana/latest/datasources/postgres/#macros) like `$__timeFilter` & `$__timeGroup` are working PostgreSQL functions like `DATE_TRUNC()` require additional treatment.

Grafana is not setting the PostgreSQL session timezone. To ensure truncation is done with respect to the Grafana timezone setting, set the [optional time_zone argument](https://www.postgresql.org/docs/current/functions-datetime.html#FUNCTIONS-DATETIME-TRUNC) for `DATE_TRUNC()`.

```sql
DATE_TRUNC('day', TIMEZONE('UTC', date), '$__timezone')
```

In addition, ensure to compare either values with or without time zone.

### Streaming API data / positions table usage in dashboard queries

When Streaming API is enabled roughly 1 GB of data is gathered per car and 30 000 km. Most of that data (95+ percent) is stored in positions table. For optimal dashboard performance these recommendations should be followed:

- only query positions table when really needed
- if data in 15 second intervals is sufficient consider excluding streaming data by adding `ideal_battery_range_km IS NOT NULL and car_id = $car_id` as WHERE conditions

Logging is much denser while driving than when parked or asleep. **Sample counts are not “time spent.”** For frequency distributions, heatmaps, or percentiles over ambient conditions, time-bucket or otherwise debiased aggregates first; do not treat raw row counts as a fair distribution.

Before opening pull requests please diagnose index usage & query performance by making use of `EXPLAIN ANALYZE`.

### Enable _pg_stat_statements_ to collect query statistics

To quickly identify performance bottlenecks we encourage all contributors to enable the pg_stat_statements extension in their instance. For docker based installs you can follow these steps:

- Enable the pg_stat_statements module

  ```yml
  services:
    database:
      image: postgres:18-trixie
      ...
      command: postgres -c shared_preload_libraries=pg_stat_statements
      ...
  ```

- Create Extension to enable `pg_stat_statements` view

  ```sql
  CREATE EXTENSION IF NOT EXISTS pg_stat_statements;
  ```

- Identify potentially slow queries (mean_exec_time)

  ```sql
  SELECT query, calls, mean_exec_time, total_exec_time FROM pg_stat_statements ORDER BY mean_exec_time DESC LIMIT 10;
  ```

- Identify frequently executed queries (calls)

  ```sql
  SELECT query, calls, mean_exec_time, total_exec_time FROM pg_stat_statements ORDER BY calls DESC LIMIT 10;
  ```

Additional details about pg_stat_statements can be found [in the PostgreSQL docs](https://www.postgresql.org/docs/current/pgstatstatements.html)

## Contributing to TeslaMate

We welcome contributions! To keep the project sustainable and legally protected, we have two main requirements for all Pull Requests:

### 1. License (AGPL-3.0-or-later)

By contributing to TeslaMate, you agree that your contributions will be licensed under the **GNU Affero General Public License v3.0 or later (AGPL-3.0-or-later)**. This ensures that the software remains free and open, even when offered as a service over a network.

### 2. Contributor License Agreement (CLA)

Before we can merge your first Pull Request, you must sign our **Fiduciary License Agreement (FLA 2.0)**.

- **Why?** This gives the `teslamate-org` the legal standing to protect the project (e.g., against trademark misuse or license violations) and guarantees that the project will **always remain Free Software**.
- **How?** When you open a PR, our `@cla-assistant` bot will post a comment with a link to sign the agreement using your GitHub account. It only takes a few seconds.
- **More Info:** You can find the full text and further details in our [Legal Repository](https://github.com/teslamate-org/legal).

## AI-assisted contributions

**Use of AI tools is welcome** for planning, implementation, tests, docs, and review drafting.

You remain fully in charge of what you submit or post:

- You must understand the change and be able to explain it.
- You are responsible for correctness, security, performance, and license compliance (AGPL-3.0-or-later / CLA).
- Review comments or replies drafted with AI are still **your** review: read and agree with every request before posting.
- Do not let an agent push, merge, or speak on GitHub on your behalf without your explicit direction and review.

For **material** AI assistance, disclose it at the end of the PR description and of substantive review comments. Include the robot icon and the **exact model name** (not only a product family):

```markdown
---

🤖 Assisted by <Exact model name> (<Vendor>) via <Tool> (<what it helped with>).
```

Examples:

```markdown
---

🤖 Assisted by Claude Opus 5 (Anthropic) via Claude Code (implementation, tests).
```

```markdown
---

🤖 Assisted by Grok 4.5 (xAI) via Grok Build (planning, code edits, PR description).
```

Trivial edits (typos, rebases) need no footer.

## Pre-Merge Checks for Dependency Updates

When reviewing a pull request that updates dependencies, it's crucial to verify that the changes are correct and don't break the Nix-based development environment. After checking out the branch of the PR, run the following commands:

- `nix flake check ...`: Verifies the flake's integrity across different systems.
- `nix build ...`: Ensures the project builds successfully with the new dependencies.
- `nix run .#lint`: Checks if the code formatting still runs.
- `devenv up`: Confirms that the development environment starts up as expected.

```bash
# Run these commands to ensure everything works as expected
nix flake check --override-input devenv-root "file+file://"<(printf %s "$PWD") . --all-systems
nix build --override-input devenv-root "file+file://"<(printf %s "$PWD")
nix run .#lint
devenv up
```

After a dependency update, refresh the hashes pinned in the flake modules:

```bash
nix run .#update-nix-hashes
```

Do not rely on the build to tell you that a hash went stale. A fixed-output derivation is addressed by its hash alone, so a stale hash resolves to the store path that was fetched for it earlier: the build succeeds, the fetcher never runs and the old content is used. The command therefore invalidates each pinned hash on purpose, lets the fetcher run and writes back the hash it reports, then builds the package once more — so a green run also means the package still builds. Expect it to take a few minutes, since it re-fetches every time by design, and if it fails it restores the hashes it had replaced.

The hash it maintains is `mixFodDeps`; npm dependencies need no hash, they are fetched from the integrity hashes in `assets/package-lock.json`.

---

### Faq (`website/docs/faq.md`)

---
title: Frequently Asked Questions
sidebar_label: FAQ
---

## How to generate your own tokens

See [Generating Tokens](installation/tokens.md).

## My car does not show up in TeslaMate

Click **Reload vehicles** on the car overview or the Settings page. TeslaMate reads the vehicle list from your Tesla account only when it starts, so a car added to the account later, the first one after sign-in or a second one after delivery, is not logged until you reload. The reload reads the list once and starts logging the new car; cars already logged are not interrupted.

If the reload finds no new car, the car is not in your Tesla account yet: wait until it shows up in the Tesla app. If the overview says that data collection is disabled, enable the car under **Settings**. If TeslaMate reports a rate limit, wait a few minutes before reloading. If you are signed out, sign in first; the vehicle list is read on sign-in.

## TeslaMate stopped recording data. How can I fix it?

Check the TeslaMate logs first. They usually show whether TeslaMate cannot reach Tesla, cannot connect to the database, or needs new credentials.

If the logs show an authentication error, use the [token generation tools](installation/tokens.md) to generate a new access token and refresh token, then enter both on the TeslaMate sign-in page. Signing in again does not remove data that TeslaMate has already recorded.

Tesla's API does not provide historical drives or charges, so TeslaMate cannot recover data that was missed while logging was stopped. If another supported logger recorded the missing period, you may be able to add it with the [TeslaFi import](import/teslafi.md).

## Why are no consumption values displayed in Grafana?

Unfortunately the Tesla API does not return consumption values for a trip. In order to still be able to display values TeslaMate estimates the consumption on the basis of the recorded (charging) data.
It takes **at least two** charging sessions before the first estimate can be displayed. Charging sessions have to be longer than 10 minutes and less than 95% state-of-charge (SoC). Each future charging session will slightly improve the accuracy of the estimate, which is applied retroactively to all data.

## Why "null" is displayed above the panels in Grafana?

If you have not customized the name of your Tesla, TeslaMate saves an empty value in the PostgreSQL database. When Grafana is reading from the database, the value `null` is the value for the variable car_id in Grafana.

Give your Tesla a name via car touchscreen and wait for TeslaMate to synchronize it.

## What is the geo-fence feature for?

At the moment geo-fences are a way to create custom locations like `🏡 Home` or `🛠️ Work` That may be particularly useful if the addresses (which are provided by [OpenStreetMap](https://www.openstreetmap.org)) in your region are inaccurate or if you street-park at locations where the exact address may vary.

## Why are my Docker timestamp logs different than my machine?

Docker container timezones default to UTC. To set the timezone for your container, use the `TZ` Environment Variable in your YML file. More information found at [Environment Variables](https://docs.teslamate.org/docs/configuration/environment_variables)

## How can I reorder my cars?

Open the Settings page and scroll to **General Settings** > **Car Order**. Use **Move up** or **Move down** next to a car to change the display order.

## Help, my car does not fall asleep

The accessory power functionality prevents your car from going to sleep even if no accessory is connected. You can disable it by setting Controls > Charging > Keep Accessory Power Off.

Cars with Media Control Unit version 1 (MCU1) require certain settings to be able to fall asleep. Model S and Model X cars built before 3/2018 have the MCU1 unit, this can also be checked from the Software -> Additional vehicle information. If the 'Infotainment processor' is 'NVIDIA Tegra', the car is equipped with MCU1.

The settings needed to enable the sleep mode with MCU1 are:

- 'Display' -> 'Energy saving' -> ON
- 'Display' -> 'Always connected' -> unchecked
- 'Safety & security' -> 'Cabin overheat protection' -> OFF

With these settings the MCU1 cars should fall asleep within some 15 minutes of inactivity. This is what you should see in the log when streaming mode is enabled in TeslaMate

- `[info] Suspending logging` after 3 minutes of inactivity (doors locked)
- `[info] Fetching vehicle state ...` about 21 minutes later. The car should have fallen asleep during this period

In this example the driver's door was opened and closed:

```bash
teslamate_1     | 2021-03-16 11:41:19.336 car_id=1 [info] Start / :online
teslamate_1     | 2021-03-16 11:41:19.603 car_id=1 [info] Connecting ...
teslamate_1     | 2021-03-16 11:44:41.380 car_id=1 [info] Suspending logging
teslamate_1     | 2021-03-16 12:03:27.356 car_id=1 [info] Fetching vehicle state ...
teslamate_1     | 2021-03-16 12:03:28.123 car_id=1 [info] Start / :asleep
teslamate_1     | 2021-03-16 12:03:28.139 car_id=1 [info] Disconnecting ...
```



**Note!** If you are using some other data logger like TeslaFi at the same time, the sleep attempts probably fail as the other data logger is keeping the car awake. Especially calling the [Vehicle Data API](https://www.teslaapi.io/vehicles/state-and-settings#vehicle-data) will reset the car's inactivity timer.

## Why am I missing data when not using the Streaming API?

The problem with the polling mode is that the car does not fall asleep before it have been inactive for some 15 minutes. TeslaMate will suspend all polling after the car has been idle for 3 minutes (the 'Idle Time Before Trying to Sleep' setting), and will resume polling 15 minutes later (the 'Time to Try Sleeping' setting).
Any activity during this 15 minutes can't be detected, as calling the [Vehicle Data API](https://www.teslaapi.io/vehicles/state-and-settings#vehicle-data) would reset the car's inactivity timer, preventing the car from falling asleep.

Calling the [Vehicle API](https://www.teslaapi.io/vehicles/list#vehicle) does not reset the inactivity timer, but it only tells if the car is either online (driving, charging, idle, about to fall asleep) or asleep. It can't tell if an idle car started driving during the 'Time to Try Sleeping' period.

## Which network flows must be authorized?

⚠️ This is for advanced users!

You might want to prohibit all network flows except those necessary for teslamate.
This is a common practice to harden an installation (e.g., to reduce the risk of data leakage).

The following flows must be authorized (egress traffic and DNS resolution):

HTTPS (TCP/443)  
auth.tesla.com  
owner-api.teslamotors.com  
streaming.vn.teslamotors.com  
nominatim.openstreetmap.org

HTTP (TCP/80)  
step.esa.int

Note: This may change when TeslaMate is updated!

## Does TeslaMate have a public API? Can I read the database directly?

There is no public API, and the database is not an interface.

**The only supported integration surface is [MQTT](integrations/mqtt.md).** This is what the [Home Assistant integration](integrations/home_assistant.md) uses. Everything else is internal.

**The PostgreSQL database is TeslaMate-internal storage, not an interface.** It has never been a documented interface and will not become one. If you read the tables directly — custom Grafana panels, scripts, third-party or commercial tools built on today's schema — expect your integration to break. Not might: will.
There is no compatibility promise and no deprecation window. We will not coordinate schema changes with external tools, and issues asking for that will be closed. Your data is safe — migrations carry it forward — but every assumption about how it is stored is up for renegotiation, and nobody outside this repository is part of that negotiation.

**The same applies to the web interface.** Its routes exist for the browser and for the dashboards we ship. None of them is a public API, none is documented, and any of them may change or disappear in any release without notice.

---

### Projects (`website/docs/projects.md`)

---
title: Projects using TeslaMate
---

Here are some projects that use **TeslaMate** as a data source to enrich its functionality and that can be useful depending on your setup.

Note that TeslaMate has [no public API and no stable database schema](faq.md#does-teslamate-have-a-public-api-can-i-read-the-database-directly). MQTT is the only supported integration surface. Tools that read the database or call internal HTTP routes will break without notice, and we will not coordinate changes with them. Some projects listed here may do exactly that. Being listed is not an endorsement and no guarantee that a project works with the current or any future TeslaMate release.
Being listed is not consent under the [Trademark Policy](https://github.com/teslamate-org/teslamate/blob/main/TRADEMARK.md); every listed project remains subject to it.

## [TeslaMate ABRP](https://fetzu.github.io/teslamate-abrp/)

A python script (also available as a lightweight docker image) that pushes car status data to [ABetterRoutePlanner](https://abetterrouteplanner.com) based on contents of TeslaMate MQTT's topic.

LINK: [github.com/fetzu/teslamate-abrp](https://github.com/fetzu/teslamate-abrp)

## [TeslaMateAgile](https://github.com/MattJeanes/TeslaMateAgile)

A TeslaMate integration for calculating cost of charges. This application will automatically update your cost for charge sessions in TeslaMate within a specified geofence (usually home) using data from your smart electricity tariff.

The supported energy providers / tariffs are either [Octopus Agile](https://octopus.energy/agile/), [Tibber](https://tibber.com/en/), [aWATTar](https://www.awattar.de/) or fixed pricing (manually specified).

LINK: [github.com/MattJeanes/TeslaMateAgile](https://github.com/MattJeanes/TeslaMateAgile)

## [TeslaMateApi](https://github.com/tobiasehlert/teslamateapi)

TeslaMateApi is a RESTful API to get data collected by self-hosted data logger TeslaMate in JSON.

The application is written in Golang and data is received from both PostgreSQL and Mosquitto and presented in various endpoints.

LINK: [github.com/tobiasehlert/TeslaMateApi](https://github.com/tobiasehlert/teslamateapi)

## [TeslaMate Custom Dashboards](https://github.com/jheredianet/Teslamate-CustomGrafanaDashboards)

TeslaMate Custom Grafana Dashboards, including: Amortization Tracker, Battery Health, Browse Charges, Charging Costs Stats, Charging CurveStats, Continuous Trips, Current State, Database Information, DC Charging Curves By Carrier, Incomplete Data, Range Degradation, Mileage Stats, Speed Rates, Speed & Temperature, Tracking Drives and more.
Also, there are two dashboards (Current Charge & Drive View) that could be browsed on the car while driving or charging.

LINK: [github.com/jheredianet/Teslamate-CustomGrafanaDashboards](https://github.com/jheredianet/Teslamate-CustomGrafanaDashboards)

## [TeslaMate Guru on Gurubase](https://gurubase.io/g/teslamate)

TeslaMate Guru is a TeslaMate-focused AI to answer your questions. It primarily uses the TeslaMate documentation and the TeslaMate GitHub repository to generate responses.

LINK: [https://gurubase.io/g/teslamate](https://gurubase.io/g/teslamate)

## [Tesla Home Assistant Integration](https://github.com/alandtse/tesla)

The Tesla Home Assistant integration can use the data from the TeslaMate MQTT integration to update car data in near-real time.

LINK: [github.com/alandtse/tesla](https://github.com/alandtse/tesla)

LINK: [Wiki How-To](https://github.com/alandtse/tesla/wiki/Teslamate-MQTT-Integration)

## [TeslaMate Telegram Bot](https://github.com/JakobLichterfeld/TeslaMate-Telegram-Bot)

This is a telegram bot written in Python to notify by Telegram message when a new SW update for your Tesla is available. It uses the MQTT topic which TeslaMate offers.

LINK: [github.com/JakobLichterfeld/TeslaMate-Telegram-Bot](https://github.com/JakobLichterfeld/TeslaMate-Telegram-Bot)

## [CustomGrafanaDashboards](https://github.com/CarlosCuezva/dashboards-Grafana-Teslamate)

Collection of custom dashboards for Grafana.

LINK: [github.com/CarlosCuezva/dashboards-Grafana-Teslamate](https://github.com/CarlosCuezva/dashboards-Grafana-Teslamate)

## [Gaussmeter](https://github.com/gaussmeter/gaussmeter)

An LED illuminated acrylic Tesla Model 3. Its color and scale of light depend on the cars current state.

LINK: [github.com/gaussmeter/gaussmeter](https://github.com/gaussmeter/gaussmeter)

## [Home Assistant Addon](https://github.com/lildude/ha-addon-teslamate)

An unofficial Home Assistant addon for TeslaMate, with a PostgreSQL addon too. Works with the existing community Grafana and Mosquitto addons to provide a complete solution.

LINK: [github.com/lildude/ha-addon-teslamate](https://github.com/lildude/ha-addon-teslamate)

## [MateDroid](https://github.com/vide/matedroid)

MateDroid is a native Android app for viewing Tesla vehicle data from your self-hosted TeslaMate instance. It uses the [TeslaMate API](https://github.com/tobiasehlert/teslamateapi) project to retrieve the data and display it in a beautiful and clean way.

LINK: [https://github.com/vide/matedroid](https://github.com/vide/matedroid)

## [MMM-Teslamate](https://github.com/denverquane/MMM-Teslamate)

A [Magic Mirror](https://magicmirror.builders/) Module for TeslaMate.

LINK: [github.com/denverquane/MMM-Teslamate](https://github.com/denverquane/MMM-Teslamate)

## [MyTeslaMate](https://www.myteslamate.com)

For those who do not wish to install their own instance, MyTeslaMate provides a managed instance of TeslaMate ready to use in one minute, with a security overlay (Authelia), 30-day backups, and the possibility of importing a backup to migrate easily.

For all TeslaMate users, MyTeslaMate also provides for free a [Fleet API](https://app.myteslamate.com/fleet) endpoint and a streaming server based on Tesla Telemetry events.

LINK: [MyTeslaMate Website](https://www.myteslamate.com)

LINK: [Follow this guide](/docs/configuration/api#myteslamate-fleet-api) to use official Tesla APIs on your TeslaMate.

## [Tesla-GeoGDO](https://github.com/brchri/tesla-geogdo) (previously [Tesla-YouQ](https://github.com/brchri/tesla-youq))

A lightweight app that will operate your smart garage door openers based on the location of your Tesla vehicles, automatically closing when you leave, and opening when you return. Supports multiple geofence types including circular, TeslaMate, and polygonal. Supports multiple vehicles and various smart garage door openers.

LINK: [https://github.com/brchri/tesla-geogdo](https://github.com/brchri/tesla-geogdo)

## [TeslaMate Achievements](https://github.com/crstian19/teslamate-achievements)

A gamification add-on for TeslaMate that analyzes your historical data to unlock achievements. It features a collection of badges based on driving milestones, charging habits, efficiency, and phantom drain, turning your ownership statistics into a fun progression system.

LINK: [github.com/crstian19/teslamate-achievements](https://github.com/crstian19/teslamate-achievements)

## [TeslaMate Dash](https://github.com/gmaslowski/teslamate-dash)

A read-only, map-first dashboard for browsing your TeslaMate history without navigating Grafana. Every drive is drawn from its GPS trace and colored by speed; drives and charges open detail panels with speed/battery charts and charging curves, and a selection of activities can be turned into a route-planner-style trip summary. Ships as a single Go binary / Docker container (multi-arch images on GHCR) with a built-in demo mode, connects to the TeslaMate Postgres database with forced read-only sessions, and sends no telemetry.

LINK: [github.com/gmaslowski/teslamate-dash](https://github.com/gmaslowski/teslamate-dash)

---

### Screenshots (`website/docs/screenshots.mdx`)

---
id: screenshots
title: Screenshots
sidebar_label: Screenshots
---

import useBaseUrl from "@docusaurus/useBaseUrl";

:::info
TeslaMate supports customizable themes. You can choose between light mode, dark mode, or system default (which automatically follows your device's appearance settings) in the Settings page.
:::

## Web Interface

<img alt="Web Interface" src={useBaseUrl("screenshots/web_interface.png")} />

## Battery Health

<img
  alt="Visited addresses"
  src={useBaseUrl("screenshots/battery-health.png")}
/>

## Charge Level

<img alt="Charge Level" src={useBaseUrl("screenshots/charge-level.png")} />

## Charges

<img alt="Charges" src={useBaseUrl("screenshots/charging-history.png")} />

## Charge Details

<img alt="Charge Details" src={useBaseUrl("screenshots/charging.png")} />

## Charging Stats

<img alt="Charge Stats" src={useBaseUrl("screenshots/charging-stats.png")} />

## Database Information

<img alt="Database Information" src={useBaseUrl("screenshots/db-info.png")} />

## Drive Stats

<img alt="Drive Stats" src={useBaseUrl("screenshots/drive-stats.png")} />

## Drives

<img alt="Drives" src={useBaseUrl("screenshots/drives.png")} />

## Drive Details

<img alt="Drive Details" src={useBaseUrl("screenshots/drive.png")} />

## Efficiency

<img alt="Efficiency" src={useBaseUrl("screenshots/efficiency.png")} />

## Location (addresses)

<img alt="Location (addresses)" src={useBaseUrl("screenshots/locations.png")} />

## Mileage

<img alt="Mileage" src={useBaseUrl("screenshots/mileage.png")} />

## Overview

<img alt="Overview" src={useBaseUrl("screenshots/overview.png")} />

## Projected Range

<img
  alt="Projected Range"
  src={useBaseUrl("screenshots/projected-range.png")}
/>

## States

<img alt="States" src={useBaseUrl("screenshots/states.png")} />

## Statistics

<img alt="Statistics" src={useBaseUrl("screenshots/statistics.png")} />

## Temperatures

<img alt="Temperatures" src={useBaseUrl("screenshots/temperatures.png")} />

## Timeline

<img alt="Timeline" src={useBaseUrl("screenshots/timeline.png")} />

## Trip

<img alt="Trip" src={useBaseUrl("screenshots/trip.png")} />

## Updates

<img alt="Updates" src={useBaseUrl("screenshots/updates.png")} />

## Vampire Drain

<img alt="Vampire Drain" src={useBaseUrl("screenshots/vampire_drain.png")} />

## Visited (Lifetime driving map)

<img
  alt="Lifetime driving map"
  src={useBaseUrl("screenshots/lifetime_driving_map.png")}
/>

---

### Upgrading (`website/docs/upgrading.mdx`)

---
id: upgrading
title: Upgrading to a new version
sidebar_label: Upgrading to a new version
---

:::warning
**Create a [backup](maintenance/backup.mdx) before updating!**
:::

:::info
**Check the [Release Notes](https://github.com/teslamate-org/teslamate/releases) for major version jumps** - some versions may require intermediate upgrades or database migrations in a specific order
:::

:::note
If you are using `docker-compose`, you are using Docker Compose v1, which has been deprecated. Docker Compose commands refer to Docker Compose v2. Consider upgrading your docker setup, see [Migrate to Compose V2](https://docs.docker.com/compose/migrate/)
:::

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

<Tabs
defaultValue="docker"
values={[
{ label: 'Docker', value: 'docker', },
{ label: 'NixOS', value: 'nixos', },
{ label: 'Manual install (Debian)', value: 'manual_debian', },
{ label: 'Manual install (FreeBSD)', value: 'manual_freebsd', },
]}>
<TabItem value="docker">

Within the directory where the YML file is located, pull the new images:

```bash
docker compose pull
```

and restart the stack with `docker compose up`. To run the containers in the background add the `-d` flag:

```bash
docker compose up -d
```

</TabItem>

<TabItem value="nixos">

These instructions assume you have installed the server using a NixOS
flake. Other methods will work, but are not documented here.

In the `inputs` section of your flake change the teslamate.url as appropriate:

```nix
teslamate.url = "github:teslamate-org/teslamate/main";
```

If you would like to pin to a specific version, you can do so for example like this:

```nix
teslamate.url = "github:teslamate-org/teslamate?rev=c37638b320e0beea97c5d51fea51cd9fdbd07ce0"; # v2.0.0
```

And update the nix flake input:

```bash
nix flake update teslamate
```

Then commit the changes to git (strongly recommended), and use your
favorite NixOS deploy tool to deploy the result.

</TabItem>

<TabItem value="manual_debian">

1. Pull the new changes from the git repository, checkout the new version and then build the new release:

   ```bash
   git pull
   git checkout $(git describe --tags `git rev-list --tags --max-count=1`)

   cd elixir
   mix deps.get --only prod
   npm install --prefix ./assets && npm run deploy --prefix ./assets

   rm -rf _build
   MIX_ENV=prod mix do phx.digest, release --overwrite
   ```

2. Most upgrades requires to run new database migrations. If so continue with the following command:

   ```bash
    _build/prod/rel/teslamate/bin/teslamate eval "TeslaMate.Release.migrate"
   ```

   Note, you may need to include environment variables when running this step:

   ```bash
    DATABASE_USER=teslamate DATABASE_PASS=super_secret_password DATABASE_NAME=teslamate DATABASE_HOST=localhost MQTT_HOST=your_MQTT_host(HomeAssistant in my case) _build/prod/rel/teslamate/bin/teslamate eval "TeslaMate.Release.migrate"
   ```

3. Finally, re-import the Grafana dashboards:

   ```bash
   LOGIN="user:pass" ../grafana/dashboards.sh restore
   ```

</TabItem>
<TabItem value="manual_freebsd">

1. Pull the new changes from the git repository, checkout the new version and then build the new release:

   ```bash
   bash

   git pull
   git checkout $(git describe --tags `git rev-list --tags --max-count=1`)

   cd elixir
   mix deps.get --only prod
   npm install --prefix ./assets && npm run deploy --prefix ./assets

   rm -rf _build
   export MIX_ENV=prod
   mix do phx.digest, release --overwrite
   ```

2. Most upgrades requires to run new database migrations. If so continue with the following command:

   ```bash
    _build/prod/rel/teslamate/bin/teslamate eval "TeslaMate.Release.migrate"
   ```

   Note: you may need to include environment variables as part of this step:

   ```bash
    DATABASE_USER=teslamate DATABASE_PASS=super_secret_password DATABASE_NAME=teslamate DATABASE_HOST=localhost MQTT_HOST=your_MQTT_host(HomeAssistant in my case) _build/prod/rel/teslamate/bin/teslamate eval "TeslaMate.Release.migrate"
   ```

3. Finally, re-import the Grafana dashboards:

   ```bash
   bash
   export LOGIN="user:pass"
   ../grafana/dashboards.sh restore
   ```

</TabItem>
</Tabs>

---

### Advanced Guides Apache (`website/docs/advanced_guides/apache.md`)

---
title: Advanced install with Apache2, TLS, HTTP Basic Auth
---

In case you wish to make TeslaMate publicly available on the Internet, it is strongly recommended to secure the web interface and allow access to Grafana only with a password. This guide provides **an example** _[docker-compose.yml](#docker-composeyml)_ which differs from the simple installation in the following aspects:

- Both publicly accessible services, TeslaMate and Grafana, sit behind a reverse proxy (Apache2) which terminates HTTPS traffic
- Ports 3000 (Grafana) and 4000 (TeslaMate) are only exposed locally
- The TeslaMate service is protected by HTTP Basic Authentication
- Custom configuration was moved into a separate `.env` file
- Grafana is configured to require a login

## Requirements

- An already installed Apache2 with the following modules:
  - `mod_proxy`
  - `mod_proxy_http`
  - `mod_proxy_wstunnel`
  - `mod_rewrite`
  - `mod_ssl`
- Two FQDN, for example `teslamate.example.com` and `grafana.example.com`
- An existing SSL certificate including the two above in `/etc/letsencrypt/live/teslamate.<your domain>`

## Instructions

Create the following files:

### docker-compose.yml

```
/* Detailed source-code truncated for AI context efficiency. */
```

### .env

This file should reside in the same folder as the docker-compose.yml file.

```plaintext title=".env"
TM_ENCRYPTION_KEY= #your secure key to encrypt your Tesla API tokens
TM_DB_USER=teslamate
TM_DB_PASS= #your secure password!
TM_DB_NAME=teslamate

GRAFANA_USER=admin
GRAFANA_PW=admin

FQDN_GRAFANA=grafana.example.com
FQDN_TM=teslamate.example.com

TM_TZ=Europe/Berlin

LETSENCRYPT_EMAIL=yourperson@example.com
```

### teslamate.conf

This file contains the definition of the virtual hosts `teslamate.example.com` and `grafana.example.com`. It has to be enabled via `a2ensite teslamate`.

This assumes, that you have the SSL certificate files residing in `/etc/letsencrypt/live/teslamate.example.com`. If it is somewhere else, you need to adapt the file accordingly.

```
/* Detailed source-code truncated for AI context efficiency. */
```

### .htpasswd

This file contains a user and password for accessing TeslaMate (Basic-auth), note this is NOT your tesla.com password. You can generate it on the web if you don't have the [Apache tools](https://www.cyberciti.biz/faq/create-update-user-authentication-files/) installed (e.g. with [htaccesstools](http://www.htaccesstools.com/htpasswd-generator/)). Use BCrypt encryption mode.

**Example:**

```apacheconf title="/etc/apache2/.htpasswd"
teslamate:$2y$10$f7PB3UF3PNzqMIXZmf1dIefOkrv/15Xt6Xw3pzc6mkS/B5qoWBdAG
```

## Usage

Start the stack with `docker compose up` run in the same directory, where the docker-compose.yml resides.

1. Open the web interface [teslamate.example.com](https://teslamate.example.com)
2. Sign in with your Tesla account
3. The Grafana dashboards are available at [grafana.example.com](https://grafana.example.com).

---

### Advanced Guides Traefik (`website/docs/advanced_guides/traefik.md`)

---
title: Advanced installation with Traefik, Let's Encrypt & HTTP Basic Auth
---

In case you wish to make TeslaMate publicly available on the Internet, it is strongly recommended to secure the web interface and allow access to Grafana only with a password. This guide provides a _[docker-compose.yml](#docker-composeyml)_ which differs from the basic installation in the following aspects:

- Both publicly accessible services, TeslaMate and Grafana, sit behind a reverse proxy (Traefik) which terminates HTTPS traffic
- The TeslaMate service is protected by HTTP Basic Authentication
- Custom configuration is held in a separate `.env` file
- A Let's Encrypt certificate is automatically acquired by Traefik
- Grafana is configured to require a login

> Please note that this is only **an example** of how TeslaMate can be used in a more advanced scenario. Depending on your use case, you may need to make some adjustments, primarily to the traefik configuration. For more information, see the [traefik docs](https://docs.traefik.io/).

## Requirements

- One public FQDN, for example `teslamate.example.com` (substitute your domainname throughout the examples below)

## Instructions

Create the following three files:

### docker-compose.yml

```
/* Detailed source-code truncated for AI context efficiency. */
```

> If you are upgrading from the [simple Docker setup](../installation/docker.md) make sure that you are using the same Postgres version as before. To upgrade to a new version see [Upgrading PostgreSQL](../maintenance/upgrading_postgres.md).

### .env

```plaintext title=".env"
TM_ENCRYPTION_KEY= #your secure key to encrypt your Tesla API tokens
TM_DB_USER=teslamate
TM_DB_PASS= #your secure password!
TM_DB_NAME=teslamate

GRAFANA_USER=admin
GRAFANA_PW=admin

FQDN_TM=teslamate.example.com

TM_TZ=Europe/Berlin

LETSENCRYPT_EMAIL=yourperson@example.com
```

> If you are upgrading from the [simple Docker setup](../installation/docker.md) make sure to use the same database and Grafana credentials as before.

### .htpasswd

This file contains a user and password for accessing TeslaMate (Basic-auth); note that this is **not** your tesla.com password. You can generate it on the web if you don't have the [Apache tools](https://www.cyberciti.biz/faq/create-update-user-authentication-files/) installed (e.g. with [htaccesstools](http://www.htaccesstools.com/htpasswd-generator/)). Use BCrypt encryption mode.

**Example:**

```apacheconf title=".htpasswd"
teslamate:$2y$10$f7PB3UF3PNzqMIXZmf1dIefOkrv/15Xt6Xw3pzc6mkS/B5qoWBdAG
```

## Usage

Start the stack with `docker compose up -d`.

1. Open the web interface `https://teslamate.example.com`
2. Sign in with your Tesla account
3. In the _Settings_ page, update the _URLs_ fields. Set _Web App_ to `https://teslamate.example.com` and _Dashboards_ to `https://teslamate.example.com/grafana`

> If you have difficulty logging into your Grafana, e.g. you cannot login with the credentials from either the simple setup or the values stored in the .env file, reset the admin password with the following command:

```bash
docker compose exec grafana grafana-cli admin reset-admin-password
```

---

### Advanced Guides Unix Domain Sockets (`website/docs/advanced_guides/unix_domain_sockets.md`)

---
title: Using Unix Domain Sockets with a reverse-proxy
---

It is possible to configure TeslaMate to communicate over unix-domain sockets (UDS) instead of a typical network socket.
This can be useful to improve security by restricting which applications can communicate to the application. A typical configuration would be to use a UDS between a reverse-proxy (like Nginx) and TeslaMate.
When paired with something like rootless-podman and [socket-activation](https://github.com/containers/podman/blob/main/docs/tutorials/socket_activation.md), Nginx can be configured with `--network=none` providing external access to TeslaMate without the Nginx container having any networking at all.
While setting up socket-activation and Podman is beyond the scope of this document, it will explain how to configure UDS between TeslaMate and an Nginx reverse-proxy.

## Requirements

- Linux system configured with TeslaMate installed and working
  - These instructions will document the procedure for using a UDS with docker-compose, but it is not difficult to adapt them to a system running TeslaMate natively via systemd.
- Nginx configured as a reverse proxy

## Instructions

Nginx requires that the UDS exist when it is started, but TeslaMate will (re)create the UDS on startup.
This means that TeslaMate must be configured to start before Nginx, or Nginx must be configured to detect a socket change and reload (for example the [socket-gen](https://github.com/PhracturedBlue/socket-gen) utility designed for this purpose). Additionally, because docker-compose does not provide a method to run host-commands prior to starting a container, the directory containing the UDS must be manually created before TeslaMate starts.
It is easiest to manually create this directory on a persistent volume.

- Create a directory for the UDS:
  `mkdir -p /opt/nginx_uds/teslamate`
- Allow Nginx to access the directory:
  `chown <nginx user> /opt/nginx_uds/teslamate`
- Allow TeslaMate to create the UDS:
  `chgrp 10001 /opt/nginx_uds/teslamate`
  `chmod 770 /opt/nginx_uds/teslamate`
  An alternative to using owner/group access would be to use [ACLs](https://wiki.debian.org/Permissions#Access_Control_Lists_in_Linux) to control access to the UDS directory.

Next configure TeslaMate to use the UDS. Modify the `teslamate` service in `docker-compose.yml` to include:

```yml
volumes: ...
  - /opt/nginx_uds/teslamate:/uds
environment: ...
  - HTTP_BINDING_ADDRESS=/uds/teslamate.sock
  - SOCKET_PERM=666
# ports:
# - 4000:4000
```

Lastly, configure the Nginx reverse-proxy to forward connections to the UDS. The relevant configuration would look something like:

```configfile
upstream teslamate.uds {
    server unix:/opt/nginx_uds/teslamate/teslamate.sock;
}

server {
    server_name teslamate;
    http2 on;
    listen 80 ;
    location / {
        proxy_pass http://teslamate.uds;
        set $upstream_keepalive false;
    }
}
```

---

### Advanced Guides Verifying Images (`website/docs/advanced_guides/verifying_images.md`)

---
title: Verifying published container images
sidebar_label: Verifying images
---

All TeslaMate images published to Docker Hub (`teslamate/teslamate`,
`teslamate/grafana`) and GitHub Container Registry
(`ghcr.io/teslamate-org/teslamate`, `ghcr.io/teslamate-org/teslamate/grafana`)
carry signed **SLSA build provenance**, generated keylessly via Sigstore using
the `teslamate-org/teslamate` GitHub Actions OIDC identity. The provenance
proves an image was built by that workflow, from a specific commit, with no
shared keys to manage.

`teslamate/teslamate` additionally carries an **SPDX SBOM** (software bill of
materials) attached to each per-platform image digest. `teslamate/grafana` is
built as a single multi-arch image and carries provenance only.

The SBOM is generated from the image by [Syft](https://github.com/anchore/syft)
and currently lists only the Debian packages and the Erlang and Elixir runtime,
not yet TeslaMate itself or its Elixir and JavaScript dependencies. Syft
detects Elixir and Erlang packages only when it scans a directory, not an
image, and the build bundles the JavaScript dependencies into single asset
files, which leave nothing Syft can recognize as a package. The package
managers' own SBOM tools cannot close the gap yet:
[mix_sbom](https://github.com/erlef/mix_sbom) also lists packages that are only
used during the build, and it gets the licenses of some packages only from the
Hex API, where a failed request drops them without an error. `npm sbom` aborts
on the Phoenix packages that the assets link from the Elixir dependencies.

## Verify with `gh`

```sh
gh attestation verify \
  oci://docker.io/teslamate/teslamate:latest \
  --repo teslamate-org/teslamate
```

Use `oci://ghcr.io/teslamate-org/teslamate:latest` for the GHCR image, and the
`grafana` variants similarly. The `gh` CLI resolves the tag to the multi-arch
manifest digest and verifies the provenance attached to it.

## Verifying per-platform SBOMs

SBOMs for `teslamate/teslamate` are attached to each per-platform image digest
(their natural scope — filesystem contents differ per architecture). To inspect,
resolve the platform digest first:

```sh
docker buildx imagetools inspect docker.io/teslamate/teslamate:latest \
  --format '{{ range .Manifest.Manifests }}{{ .Platform.Architecture }} {{ .Digest }}{{ "\n" }}{{ end }}'

gh attestation verify \
  oci://docker.io/teslamate/teslamate@sha256:<platform-digest> \
  --repo teslamate-org/teslamate \
  --predicate-type https://spdx.dev/Document
```

---

### Configuration Api (`website/docs/configuration/api.md`)

---
title: Using the Tesla Fleet API and Telemetry Streaming (only for business fleet users)
---

## Official Tesla APIs

### Why Tesla Fleet and Telemetry only have drawbacks

As far as we know, using the Tesla Fleet API and Telemetry API as a user has only drawbacks. The only reason to use them is if you are a Tesla Business Fleet user and therefore the Owner API is no longer available for you.

### When Tesla Fleet API and Telemetry API are needed

By default, TeslaMate uses the "_unofficial_" Owner API and streaming.

Tesla now provides official APIs: the Fleet API and the Telemetry API, which replace the Owner API and streaming respectively. But come with limitations and drawbacks.

**Migration to the new API depends on your Tesla account type:**

1. **_[Tesla Business Fleet users](https://www.tesla.com/fleet):_** the Owner API is [being shut down](https://developer.tesla.com/docs/fleet-api#2024-03-26-shutting-down-legacy-vehicle-api-endpoints). Fleet vehicles are upgraded gradually and an error message means that they must now use the official API.

2. **_Individual users:_** the Owner API is currently still accessible.

**Resume: if you are a Tesla Business Fleet user, you should migrate to the official API ASAP!** The official Tesla API will only become mandatory when the Owner API shuts down for all users. Until then you can and should continue to use the Owner API, as it is more feature-rich and has higher resolution streaming.

### Impacts/Limitations of New Endpoints

#### Tesla Fleet API: very limited recording resolution

The [Fleet API](https://developer.tesla.com/docs/fleet-api) is similar to the Owner API but more comprehensive. However, retrieving vehicle information (`vehicle_data`) or sending commands is limited. The limits on the Owner API were historically much higher. It is likely that [these limits](https://developer.tesla.com/docs/fleet-api#membership-levels) will also be applied soon to the API Owner.

#### Tesla Fleet Telemetry: non compatible by default

The [Tesla Fleet Telemetry](https://github.com/teslamotors/fleet-telemetry) differs from the "Owner" streaming. By default, metrics are sent to message queues instead of a websocket as streaming did. Historical streaming could send events every second, whereas Fleet Telemetry will only send information every minute at the minimum.

#### How to Use Tesla APIs

The setup to use the official Tesla APIs ([described below](#tesla-fleet-api)) is complex.
You can use a [third-party providers](#guide-for-third-party-providers) to easily access these APIs.

## Guide for Third-Party Providers

Environment variables allow changing the API and streaming endpoints.
You must use the `URL` and the `TOKEN` given by the third party API provider.

### [MyTeslaMate](https://www.myteslamate.com) (free)

#### MyTeslaMate Fleet API

1. Log in the [MyTeslaMate](https://app.myteslamate.com) website **with your Tesla account** and go to the [MyTeslaMate Fleet](https://app.myteslamate.com/fleet) page to get your `TOKEN`.
1. Add the following environment variables (using your `TOKEN` instead of _`xxxx-xxxx-xxxx-xxxx`_):

```yml
# API Fleet
- TOKEN=xxxx-xxxx-xxxx-xxxx
- TESLA_API_HOST=https://api.myteslamate.com
- TESLA_AUTH_HOST=https://api.myteslamate.com
- TESLA_AUTH_PATH=/api/oauth2/v3
```

#### MyTeslaMate Streaming

MyTeslaMate also provides streaming by [reproducing the old streaming from the data sent by Fleet Telemetry](https://github.com/MyTeslaMate/websocket).

1. You need to "_Pair your vehicle(s)_" on the [fleet](https://app.myteslamate.com/fleet) page
1. Use the following dedicated environment variables:

   ```yml
   - TESLA_WSS_HOST=wss://streaming.myteslamate.com
   - TESLA_WSS_TLS_ACCEPT_INVALID_CERTS=true
   - TESLA_WSS_USE_VIN=true
   ```

1. Restart your instance

### [Teslemetry](https://teslemetry.com/pricing) (paid)

#### Teslemetry Fleet API

**_Important: Teslemetry's vehicle data polling is [pay-per-use](https://teslemetry.com/blog/road-away-from-polling)._**

1. Log in the [Teslemetry website](https://teslemetry.com) and create your `TOKEN`.
1. Use this `TOKEN` instead of _`xxxx-xxxx-xxxx-xxxx`_ and add the following environment variables:

   ```yml
   - TOKEN=xxxx-xxxx-xxxx-xxxx
   - TESLA_API_HOST=https://api.teslemetry.com
   - TESLA_AUTH_HOST=https://api.teslemetry.com
   - TESLA_AUTH_PATH=/api/oauth2/v3
   ```

1. Restart your instance

#### Teslemetry Streaming

**_Important: Teslemetry's streaming is incompatible with TeslaMate, you MUST disable manually the streaming in TeslaMate settings._**

## Guide to using the official Tesla API directly (free)

### Requirements

- Advanced IT skills
- A dedicated public hosting
- A [free Tesla Fleet API plan](https://developer.tesla.com/docs/fleet-api#membership-levels)

### Tesla Fleet API

1. Set up a third-party account at [developer.tesla.com](https://developer.tesla.com) as described on the [Tesla docs](https://developer.tesla.com/docs/fleet-api#setup)
1. Add the following environment variable with your own domain :
   1. Use [the correct region](https://developer.tesla.com/docs/fleet-api#endpoints-and-regional-requirements) in the `TESLA_API_HOST` field:
      - North America, Asia-Pacific (excluding China): [https://fleet-api.prd.na.vn.cloud.tesla.com](https://fleet-api.prd.na.vn.cloud.tesla.com)
      - Europe, Middle East, Africa: [https://fleet-api.prd.eu.vn.cloud.tesla.com](https://fleet-api.prd.eu.vn.cloud.tesla.com)
      - China: [https://fleet-api.prd.cn.vn.cloud.tesla.cn](https://fleet-api.prd.cn.vn.cloud.tesla.cn)
   1. Update the `TESLA_AUTH_CLIENT_ID` with the client ID of your Tesla application.

   ```yml
   # API Fleet
   - TESLA_API_HOST=https://fleet-api.prd.eu.vn.cloud.tesla.com
   - TESLA_AUTH_HOST=https://auth.tesla.com
   - TESLA_AUTH_PATH=/oauth2/v3
   - TESLA_AUTH_CLIENT_ID=xxxxxxxxx-xxxx-xxxx-xxxxxxxxxxxx
   ```

1. (Optional) If you want to send commands or use Tesla Telemetry:
   1. Send drivers a "Pairing request" to be able to use your own [Tesla Vehicle Command Protocol http proxy to send commands](https://github.com/teslamotors/vehicle-command?tab=readme-ov-file#using-the-http-proxy)
   2. Send test commands or setup Telemetry to [stream it to your TeslaMate](#streaming-via-tesla-telemetry)

#### Switching from Owners API to Fleet API

1. Sign out from the current Owners API by visiting the TeslaMate settings page
2. Follow step 1&2 from [Tesla Fleet API](https://docs.teslamate.org/docs/guides/api#tesla-fleet-api)
3. Restart your docker instance to make the change in effect
4. With proper setup, your TeslaMate instance will sign in automatically with your client ID after restart

### Streaming via Tesla Telemetry

**_Important: if you don't setup your own streaming, you MUST disable manually the streaming in TeslaMate settings._**

To setup your own streaming server, you can follow these steps:

1. Setup a [Tesla Fleet Telemetry](https://github.com/teslamotors/fleet-telemetry) instance on a public domain (eg: _telemetry.mydomain.com_)
1. Add a [Google pubsub dispatcher](https://github.com/teslamotors/fleet-telemetry?tab=readme-ov-file#backendsdispatchers) to your own GCP PubSub.
1. Setup a [MyTeslaMate Streaming Server from Fleet Telemetry Events](https://github.com/MyTeslaMate/websocket) on a public domain (eg: _streaming.mydomain.com_)
1. Manually create a subscription to the `telemetry_V` created in PubSub by the Tesla Telemetry with:
   - Delivery type: Push
   - Endpoint URL: [https://streaming.mydomain.com](https://streaming.mydomain.com)
1. Update your environment variables:

   ```yml
   - TESLA_WSS_HOST=wss://streaming.mydomain.com
   - TESLA_WSS_TLS_ACCEPT_INVALID_CERTS=true
   - TESLA_WSS_USE_VIN=true
   ```

1. Restart your instance

---

### Configuration Environment Variables (`website/docs/configuration/environment_variables.md`)

---
id: environment_variables
title: Environment Variables
sidebar_label: Environment Variables
---

TeslaMate accepts the following environment variables for runtime configuration:

| Variable Name                            | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | Default Value                                                                                                                                                       |
| ---------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **ENCRYPTION_KEY**                       | A key used to encrypt the Tesla API tokens (**required**)                                                                                                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                     |
| **DATABASE_USER**                        | Username. Also used with `DATABASE_SOCKET_DIR` when the socket connection requires password authentication.                                                                                                                                                                                                                                                                                                                                                                                            |                                                                                                                                                                     |
| **DATABASE_PASS**                        | User password. Also used with `DATABASE_SOCKET_DIR` when the socket connection requires password authentication.                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                     |
| **DATABASE_NAME**                        | The database to connect to                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                     |
| **DATABASE_HOST**                        | Hostname of the database server                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                     |
| **DATABASE_PORT**                        | Port of the database server                                                                                                                                                                                                                                                                                                                                                                                                                                                                            | 5432                                                                                                                                                                |
| **DATABASE_SOCKET_DIR**                  | Local path containing a UNIX socket for the database. `DATABASE_USER` and `DATABASE_PASS` are honored when set; omit them to use peer authentication.                                                                                                                                                                                                                                                                                                                                                  |                                                                                                                                                                     |
| **DATABASE_POOL_SIZE**                   | Size of the database connection pool                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 10                                                                                                                                                                  |
| **DATABASE_TIMEOUT**                     | The time in milliseconds to wait for database query calls to finish                                                                                                                                                                                                                                                                                                                                                                                                                                    | 60000                                                                                                                                                               |
| **DATABASE_SSL**                         | Set to `true` if SSL should be enabled or `noverify` if certificate verification should not be performed.                                                                                                                                                                                                                                                                                                                                                                                              | false                                                                                                                                                               |
| **DATABASE_SSL_CA_CERT_FILE**            | Path to a file containing PEM-encoded CA certificates (required if `DATABASE_SSL` is set to `true`)                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                     |
| **DATABASE_SSL_SNI**                     | set SNI for host under SSL mode                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |                                                                                                                                                                     |
| **DATABASE_IPV6**                        | Set to `true` if IPv6 should be used                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | false                                                                                                                                                               |
| **VIRTUAL_HOST**                         | Host part used for generating URLs throughout the app                                                                                                                                                                                                                                                                                                                                                                                                                                                  | localhost                                                                                                                                                           |
| **URL_PATH**                             | Path used for generating URLs (can be used with a reverse proxy)                                                                                                                                                                                                                                                                                                                                                                                                                                       | /                                                                                                                                                                   |
| **CHECK_ORIGIN**                         | Configures whether to check the origin header or not. May be `true` (**recommended**), `false` (_default_) or a comma-separated list of hosts that are allowed (e.g. `https://example.com,//another.com:8080`). Hosts also support wildcards. If `true`, it will check against the host value in `VIRTUAL_HOST`.                                                                                                                                                                                       | false                                                                                                                                                               |
| **PORT**                                 | Port where the web interface is exposed                                                                                                                                                                                                                                                                                                                                                                                                                                                                | 4000                                                                                                                                                                |
| **HTTP_BINDING_ADDRESS**                 | IP address where the web interface is exposed, or blank (_default_) meaning all addresses.                                                                                                                                                                                                                                                                                                                                                                                                             |                                                                                                                                                                     |
| **DISABLE_MQTT**                         | Disables the MQTT feature if `true`                                                                                                                                                                                                                                                                                                                                                                                                                                                                    | false                                                                                                                                                               |
| **MQTT_HOST**                            | Hostname of the broker (**required** unless DISABLE_MQTT is `true`)                                                                                                                                                                                                                                                                                                                                                                                                                                    |                                                                                                                                                                     |
| **MQTT_PORT**                            | Port of the broker                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     | 1883 (8883 for MQTT over TLS)                                                                                                                                       |
| **MQTT_USERNAME**                        | Username                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                     |
| **MQTT_PASSWORD**                        | Password                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                     |
| **MQTT_TLS**                             | Enables TLS if `true`                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  | false                                                                                                                                                               |
| **MQTT_TLS_ACCEPT_INVALID_CERTS**        | Accepts invalid certificates if `true`                                                                                                                                                                                                                                                                                                                                                                                                                                                                 | false                                                                                                                                                               |
| **MQTT_IPV6**                            | Set to `true` if IPv6 should be used                                                                                                                                                                                                                                                                                                                                                                                                                                                                   | false                                                                                                                                                               |
| **MQTT_NAMESPACE**                       | Inserts a custom namespace into the MQTT topic. For example, with `MQTT_NAMESPACE=account_0`: `teslamate/account_0/cars/$car_id/state`.                                                                                                                                                                                                                                                                                                                                                                |                                                                                                                                                                     |
| **MQTT_HOME_ASSISTANT_DISCOVERY**        | Enables Home Assistant MQTT discovery if `true`. TeslaMate publishes discovery config payloads to `<MQTT_HOME_ASSISTANT_DISCOVERY_PREFIX>/.../config` so entities appear in Home Assistant automatically, removing the need for the manual `mqtt_sensors.yaml`. Optionally set together with `MQTT_HOME_ASSISTANT_DISCOVERY_URL`. If not `true`, TeslaMate clears its discovery topics on every start, see [MQTT discovery](../integrations/home_assistant.md#mqtt-discovery-automatic-configuration). | false                                                                                                                                                               |
| **MQTT_HOME_ASSISTANT_DISCOVERY_URL**    | Optional: the TeslaMate URL surfaced in the discovered device panel (e.g. `https://teslamate.example.com/`). Only used when `MQTT_HOME_ASSISTANT_DISCOVERY` is `true`.                                                                                                                                                                                                                                                                                                                                 |                                                                                                                                                                     |
| **MQTT_HOME_ASSISTANT_DISCOVERY_PREFIX** | Discovery topic prefix. Matches Home Assistant's MQTT discovery prefix.                                                                                                                                                                                                                                                                                                                                                                                                                                | homeassistant                                                                                                                                                       |
| **IMPORT_DIR**                           | The path of the directory for the import of data (e.g. TeslaFi)                                                                                                                                                                                                                                                                                                                                                                                                                                        | ./import                                                                                                                                                            |
| **TZ**                                   | Used to establish the local time zone, e.g. to use the local time in logs. See [List of tz database time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).                                                                                                                                                                                                                                                                                                                         |                                                                                                                                                                     |
| **DEFAULT_GEOFENCE**                     | The default GEOFENCE to send via GEOFENCE if car not in geofence. Overrides the default of "" which will delete any retained value.                                                                                                                                                                                                                                                                                                                                                                    | "" (no quotes)                                                                                                                                                      |
| **TESLAFI_IMPORT_VEHICLE_ID**            | The default Vehicle ID used when importing from TeslaFi. If it is not defined and the import source does not contain the data, 1 is used.                                                                                                                                                                                                                                                                                                                                                              |                                                                                                                                                                     |
| **TESLA_API_HOST**                       | Hostname of the Tesla API                                                                                                                                                                                                                                                                                                                                                                                                                                                                              | [https://owner-api.teslamotors.com](https://owner-api.teslamotors.com) (or for chinese: [https://owner-api.vn.cloud.tesla.cn](https://owner-api.vn.cloud.tesla.cn)) |
| **TESLA_API_POOL_SIZE**                  | HTTP pool size limit for `TESLA_API_HOST` domain API                                                                                                                                                                                                                                                                                                                                                                                                                                                   | 10                                                                                                                                                                  |
|                                          |
| **TESLA_AUTH_HOST**                      | Hostname of the Tesla authentication API                                                                                                                                                                                                                                                                                                                                                                                                                                                               | [https://auth.tesla.com](https://auth.tesla.com)                                                                                                                    |
| **TESLA_AUTH_PATH**                      | The Tesla authentication path                                                                                                                                                                                                                                                                                                                                                                                                                                                                          | /oauth2/v3                                                                                                                                                          |
| **TESLA_AUTH_CLIENT_ID**                 | Client ID of the application registered on [developer.tesla.com](https://developer.tesla.com)                                                                                                                                                                                                                                                                                                                                                                                                          | ownerapi                                                                                                                                                            |
| **TESLA_WSS_HOST**                       | Hostname of the Tesla streaming                                                                                                                                                                                                                                                                                                                                                                                                                                                                        | wss://streaming.vn.teslamotors.com (or for chinese: wss://streaming.vn.cloud.tesla.cn)                                                                              |
| **TESLA_WSS_TLS_ACCEPT_INVALID_CERTS**   | Accepts invalid certificates on TESLA_WSS_HOST if `true`                                                                                                                                                                                                                                                                                                                                                                                                                                               |                                                                                                                                                                     |
| **TESLA_WSS_USE_VIN**                    | Use the `vin` field instead of `vid` to connect stream if `true`                                                                                                                                                                                                                                                                                                                                                                                                                                       |                                                                                                                                                                     |
| **TOKEN**                                | Token given by a third party Tesla API provider. It is sent as an `Authorization: Bearer` header on each API request (and in the streaming subscribe message), so provide only the raw token, e.g. `xxxx-xxxx-xxxx`. For backward compatibility the legacy `?token=xxxx-xxxx-xxxx` format is still accepted.                                                                                                                                                                                           |                                                                                                                                                                     |
| **POLLING_ASLEEP_INTERVAL**              | Interval between API fetch when the vehicle is asleep (in seconds). **Important: Do not alter this setting unless you are certain of the implications.**                                                                                                                                                                                                                                                                                                                                               | 30                                                                                                                                                                  |
| **POLLING_CHARGING_INTERVAL**            | Minimum interval between API fetch when the vehicle is charging (in seconds). **Important: Do not alter this setting unless you are certain of the implications.**                                                                                                                                                                                                                                                                                                                                     | 5                                                                                                                                                                   |
| **POLLING_DRIVING_INTERVAL**             | Interval between API fetch when the vehicle is driving (in seconds). **Important: Do not alter this setting unless you are certain of the implications.**                                                                                                                                                                                                                                                                                                                                              | 2.5                                                                                                                                                                 |
| **POLLING_ONLINE_INTERVAL**              | Interval between API fetch when the vehicle is online (in seconds). **Important: Do not alter this setting unless you are certain of the implications.**                                                                                                                                                                                                                                                                                                                                               | 60                                                                                                                                                                  |
| **POLLING_DEFAULT_INTERVAL**             | Default interval between API fetch (in seconds). **Important: Do not alter this setting unless you are certain of the implications.**                                                                                                                                                                                                                                                                                                                                                                  | 15                                                                                                                                                                  |
| **POLLING_MINIMUM_INTERVAL**             | Minimum interval between API fetch. No minimum by default. **Important: Do not alter this setting unless you are certain of the implications.**                                                                                                                                                                                                                                                                                                                                                        | 0                                                                                                                                                                   |
| **HTTP_POOL_SIZE**                       | The default size of the HTTP connection pool for domains other than `TESLA_API_HOST`, `nominatim.openstreetmap.org`, and `api.github.com`. This setting determines the maximum number of simultaneous connections allowed for these domains.                                                                                                                                                                                                                                                           | 5                                                                                                                                                                   |
| **HTTP_POOL_TIMEOUT**                    | The maximum time (in microseconds) to wait for a connection from the HTTP pool before timing out. This setting helps prevent indefinite waits when the pool is exhausted.                                                                                                                                                                                                                                                                                                                              | 10000                                                                                                                                                               |
| **ULIMIT_MAX_NOFILE**                    | Sets the maximum number of open file descriptors for the TeslaMate process. This can prevent memory bloat in environments with very high default `ulimit` values. Set to `0` to disable this feature.                                                                                                                                                                                                                                                                                                  | 65536                                                                                                                                                               |
| **NOMINATIM_PROXY**                      | HTTP proxy for OpenStreetMap Nominatim API requests (e.g. `http://127.0.0.1:7897`, HTTP only). Similar to [`nominatim_http_proxy`](https://nominatim.org/release-docs/latest/customize/Settings/#nominatim_http_proxy).                                                                                                                                                                                                                                                                                |                                                                                                                                                                     |

---

### Import Tesla Apiscraper (`website/docs/import/tesla_apiscraper.md`)

---
title: Import from tesla-apiscraper (BETA)
sidebar_label: tesla-apiscraper
---

This is a multi-step process to export your data from a [tesla-apiscraper](https://github.com/lephisto/tesla-apiscraper) InfluxDB backend, convert it to a format that can be imported into TeslaMate (specifically TeslaFi CSV) while fixing up some typical data glitches the scraper produces, and then import it.

## Requirements

- A copy of the data stored by `tesla-apiscraper` - specifically the `/opt/apiscraper/influxdb` folder mounted in the standard apiscraper Docker configuration. **Create a backup of this** before attempting the export and conversion, just in case.

- A system running Docker with sufficient RAM for InfluxDB to perform the CSV export. This does **not** need to be the same machine where API Scraper and/or TeslaMate was/is running - you can do the export and conversion on your PC/Mac. The important thing is to give the Docker machine more than 2GB of RAM, otherwise the InfluxDB export may fail.

- **CREATE A [BACKUP](../maintenance/backup.mdx) OF YOUR DATA** before attempting to import anything into TeslaMate. This is all highly experimental and has only been successfully done once :)

## Instructions

:::note Troubleshooting
All of this is experimental and has not been extensively tested. If you encounter an error during Part 1 or Part 2, please create an issue in the [tesla-apiscraper-to-teslafi-export](https://github.com/olexs/tesla-apiscraper-to-teslafi-export) project on GitHub, since it's not directly related to TeslaMate.
:::

### Part 1: Exporting the API Scraper InfluxDB data into CSV

1. Download or clone the [tesla-apiscraper-to-teslafi-export](https://github.com/olexs/tesla-apiscraper-to-teslafi-export) repository into a folder on your machine.

2. Place the `tesla-apiscraper` data folder _contents_ (_data_, _meta_ and _wal_ folders) into the `influxdb-data` folder, next to the `influxdb-export.sh` file. The folder structure must look like this:

   ```console
   .
   ├── influxdb-export.sh
   ├── influxdb-export.bat
   ├── (other stuff)
   └── influxdb-data
       ├── README.md
       ├── data
       ├── meta
       └── wal
   ```

3. Run the `influxdb-export.sh` script (or `influxdb-export.bat` if you're on Windows). You may need to `sudo` it / run it in an Administrator command line prompt if your Docker install needs root. It will do the following:
   - Create the `influxdb-csv` output folder, if it doesn't exist yet
   - Start an InfluxDB Docker container with the `influxdb-data` and `influxdb-csv` folders mounted (on Windows, you may need to allow your Docker to access the drive you are working on for the mounts to work)
   - Wait for the container to report as _healthy_
   - Execute the export commands for all data stored by apiscraper, putting the CSV files inside the `influxdb-csv` folder
   - Stop and delete the InfluxDB container

   This may take a little while. After the process has finished, if there are no errors reported, continue with the next part of the instructions.

### Part 2: Converting exported InfluxDB CSV files to TeslaFi CSV

1. Obtain your Tesla's **vehicle ID** number. It's a 10- or 11-digit number that uniquely identifies your car, and is part of the TeslaFi data format, but it's not included in tesla-apiscraper data - so you need to source it separately. There are several ways you can get it:
   - Manually using the Tesla API. The number is listed under `vehicle_id` in the `vehicles` response, as documented here: [https://tesla-api.timdorr.com/api-basics/vehicles](https://tesla-api.timdorr.com/api-basics/vehicles).
   - From the database of another Tesla API tracker you're already using, such as TeslaMate (**docker compose exec database psql teslamate teslamate -c 'select vid from cars;'**).

2. Run the `teslafi-convert.sh` script (or `teslafi-convert.bat` if you're on Windows). You may need to `sudo` it / run it in an Administrator command line prompt if your Docker install needs root. It will do the following:
   - Create the `teslafi-csv` output folder, if it doesn't exist yet
   - Build and start a Docker container with the `converter` app and its few dependencies, with the `influxdb-csv` and `teslafi-csv` folders mounted (on Windows, you may need to allow your Docker to access the drive you are working on for the mounts to work)
   - Ask you for the vehicle ID mentioned above
   - Process the CSV files in the `influxdb-csv` folder. This may take a couple minutes. Progress is displayed as the converter works its way through the files
   - Stop and delete the Docker container

   The finished TeslaFi-compatible CSV files are now located in the `teslafi-csv` folder.

### Part 3: Importing the processed CSV data into TeslaMate

- Proceed with the [TeslaFi import](teslafi.md) steps using the CSV files you just created.

---

### Import Teslafi (`website/docs/import/teslafi.md`)

---
title: Import from TeslaFi (BETA)
sidebar_label: TeslaFi
---

## Requirements

- **CREATE A [BACKUP](../maintenance/backup.mdx) OF YOUR DATA‼️**

- If you have been using TeslaMate since before the 1.16 release, the [docker-compose.yml](../installation/docker.md) needs to be updated. Add the following volume mapping to the `teslamate` service:

  ```yml {4-5}
  services:
    teslamate:
      # ...
      volumes:
        - ./import:/opt/app/import
  ```

- Export your TeslaFi data (for one car) as CSV by month: `Settings -> Advanced -> Download TeslaFi Data`.

<details>
  <summary>If you have a ton of TeslaFi data and don't want to deal with the UI, you can run this python script to export all data</summary>

```
/* Detailed source-code truncated for AI context efficiency. */
```

</details>

## Instructions

1. Copy the exported CSV files (in the format "TeslaFixxxxxx.csv") into a **directory named `import`** next to the _docker-compose.yml_:

   ```console
   .
   ├── docker-compose.yml
   └── import
       ├── TeslaFi82019.csv
       ├── TeslaFi92019.csv
       ├── TeslaFi102019.csv
       ├── TeslaFi112019.csv
       └── TeslaFi122019.csv
   ```

   :::tip
   The path of the import directory can be customized with the **IMPORT_DIR** [environment variable](../configuration/environment_variables.md).
   :::

2. **Restart** the `teslamate` service and open the TeslaMate admin interface. Now the import form should be displayed instead of the vehicle summary.
3. Since the raw data is in the local timezone (assigned by the home address in the TeslaFi settings page) you need to **select your local timezone**. Then start the import. On low-end hardware like the Raspberry Pi, importing a large data set spanning several years will take a couple of hours.
4. After the import is complete, **empty the `import` directory** (or remove but ensure docker doesn't have a volume mapping) and **restart** the `teslamate` service.
5. Reindex PostgreSQL data: `REINDEX TABLE positions;`

:::caution
If an individual CSV row cannot be parsed or contains values that TeslaMate cannot safely store,
TeslaMate skips that row and continues with the remaining valid rows. The import page lists the
source file, CSV row number, and invalid field names without displaying the row's values. Review
that report before removing the import files. The raw-free rejection details persist if the import
is interrupted. A skipped row can make a nearby drive or charging summary incomplete.
:::

:::note
If TeslaMate restarts during an import, it skips only files that reached a committed file boundary
and whose content fingerprint still matches. The file that was active during the interruption is
processed again from its beginning. Rows already stored from that file may be imported again. This
is file-level recovery, not row-exact or exactly-once recovery; keep the original CSV files
unchanged until the import finishes. TeslaMate also keeps the time zone selected when the run
started and reuses it after a restart so timestamps cannot shift partway through the import.

If the saved time zone is wrong or the source files were replaced, use **Discard interrupted
import** before starting again. The saved checkpoints and rejection report for that run are no
longer used. Data already imported into TeslaMate is not deleted.
:::

:::note
If there is an overlap between the already existing TeslaMate and TeslaFi data, only the data prior to the first TeslaMate data will be imported.
:::

:::note
If the CSV files are missing the vehicle ID, the imported will default to `1`. You can alter this behavior by setting the environment variable `TESLAFI_IMPORT_VEHICLE_ID`.
:::

:::note
Since the exported CSV files do not contain addresses, they are added automatically during and after the import. So please note that not all addresses are visible immediately after the import/restarting. Depending on the amount of data imported, it may take a while before they appear. The same applies to elevation data.
:::

---

### Installation Docker (`website/docs/installation/docker.md`)

---
title: Docker install
sidebar_label: Docker
---

This document provides the necessary steps for installation of TeslaMate on any system that runs Docker. You run NixOS? We got you covered, see [NixOS install](nixos.md).

:::info
This setup is recommended only if you are running TeslaMate **on your home network**, as otherwise your Tesla API tokens might be at risk.
If you intend to access TeslaMate from the Internet, the recommended way is to use a secure connection (such as a VPN, Cloudflare Tunnel, Tailscale, Zero Tier and a reverse proxy for portless access) for secured access to your TeslaMate instance outside your home network.
Alternatively, you can use a reverse proxy (such as Traefik, Apache2 or Caddy) with appropriate hardening to secure your TeslaMate instance before exposing it to the internet, check out the [advanced guides with Traefik](../advanced_guides/traefik.md) for an example how to use Traefik with TeslaMate. Or you can use the [advanced guides with Apache](../advanced_guides/apache.md) to set up TeslaMate with Apache2, TLS and HTTP Basic Auth.
:::

## Requirements

- Docker _(if you are new to Docker, see [Installing Docker](https://docs.docker.com/engine/install/) and [Docker Compose](https://docs.docker.com/compose/install/linux/))_
- A Machine that's always on, so TeslaMate can continually fetch data
- At least 1 GB of RAM on the machine for the installation to succeed. It is recommended to have at least 2 GB of RAM for optimal operation.
- External internet access, to talk to tesla.com
- Docker images are available for aarch64 (ARM 64-bit) and amd64 (Intel/AMD 64-bit). For Raspberry Pi users: armv7 is no longer supported. You must use a 64-bit Raspberry Pi OS with an ARMv8-compatible board (Raspberry Pi 3 or newer)

## Instructions

1. Create a file called `docker-compose.yml` with the following content:

   ```
/* Detailed source-code truncated for AI context efficiency. */
```

2. **Choose a secure encryption key** that will be used to encrypt your Tesla API tokens (insert as `ENCRYPTION_KEY`).
3. **Choose your secure database password** and insert it at every occurrence of `DATABASE_PASS` and `POSTGRES_PASSWORD`
4. Start the docker containers with `docker compose up`. To run the containers in the background add the `-d` flag:

   ```bash
   docker compose up -d
   ```

## Usage

1. [Generate an access and refresh token](tokens.md)
2. Open the web interface [http://your-ip-address:4000](http://localhost:4000)
3. Enter the access and refresh token on the sign-in page
4. The Grafana dashboards are available at [http://your-ip-address:3000](http://localhost:3000). Log in with the default user `admin` (initial password `admin`) and enter a secure password.
5. In the TeslaMate web interface, go to _Settings → URLs_ and set the _Web App_ and _Dashboards_ URLs, so the links between TeslaMate and Grafana work in both directions.

## Update

To update the running TeslaMate configuration to the latest version, follow: [Upgrading to a new version](../upgrading.mdx)

---

### Installation Nixos (`website/docs/installation/nixos.md`)

---
title: NixOS install
sidebar_label: NixOS
---

This document provides the necessary steps for installation of TeslaMate on [NixOS](https://nixos.org/).

:::info
This setup is recommended only if you are running TeslaMate **on your home network**, as otherwise your Tesla API tokens might be at risk.

If you intend to access TeslaMate from the Internet, the recommended way is to use a secure connection (such as a VPN, Cloudflare Tunnel, Tailscale, Zero Tier and a reverse proxy for portless access like [Caddy](https://nixos.wiki/wiki/Caddy)) for secured access to your TeslaMate instance outside your home network.
Alternatively, you can use a reverse proxy (such as Traefik or [Caddy](https://nixos.wiki/wiki/Caddy)) with appropriate hardening to secure your TeslaMate instance before exposing it to the internet.
:::

## Requirements

- NixOS _(if you are new to NixOS, see [NixOS getting started](https://nixos.org/learn/))_
- A Machine that's always on, so TeslaMate can continually fetch data
- At least 1 GB of RAM on the machine for the installation to succeed. It is recommended to have at least 2 GB of RAM for optimal operation.
- External internet access, to talk to tesla.com

## Instructions

We provide a flake module that can be used to install TeslaMate on NixOS. To use it, you need to have Nix flakes enabled. If you don't have them enabled yet, follow the [NixOS documentation](https://nixos.wiki/wiki/Flakes).

The options for the module are documented in the [module.nix](https://github.com/teslamate-org/teslamate/blob/48fb4fa2675ed742bf1b125a784dbbbcb1aceb24/nix/module.nix).

In the `inputs` section of your flake add:

```nix
teslamate.url = "github:teslamate-org/teslamate/main";
```

If you would like to pin to a specific version, you can do so for example like this:

```nix
teslamate.url = "github:teslamate-org/teslamate?rev=c37638b320e0beea97c5d51fea51cd9fdbd07ce0"; # v2.0.0
```

To enable the TeslaMate service, your config could look like this (note: this will conflict with any existing PostgreSQL/Grafana servers, because NixOS modules do not support multiple instances).

```nix
{
  config,
  lib,
  inputs,
  ...
}:
{
imports = [ inputs.teslamate.nixosModules.default ];

config = services.teslamate = {
      enable = true;
      secretsFile = "/run/secrets/teslamate.env"; # you can use agenix for sure: config.age.secrets.teslamateEnv.path;
      # the secrets file must contain at least:
      #  - `ENCRYPTION_KEY` - encryption key used to encrypt database
      #  - `DATABASE_PASS` - password used to authenticate to database
      #  - `RELEASE_COOKIE` - unique value used by elixir for clustering
      autoStart = true;
      listenAddress = "127.0.0.1";
      port = 4000;
      virtualHost = "$[your-domain]";
      urlPath = "/";

      postgres = {
        enable_server = true;
        user = "teslamate";
        database = "teslamate";
        host = "127.0.0.1";
        port = 5432;
      };

      grafana = {
        enable = true;
        listenAddress = "127.0.0.1";
        port = 3000;
        urlPath = "/";
      };

      mqtt = {
        enable = true;
        host = "127.0.0.1";
        port = 1883;

        # Optional: Home Assistant MQTT discovery
        discovery = {
          enable = true;
          url = "https://teslamate.example.com/";
        };
      };
    };
}
```

If you want to use the TeslaMate web interface via a reverse proxy, you can use the following snippet if you have already Caddy service running:

```nix
{
    services.caddy.virtualHosts."[your-sub-domain for TeslaMate]" = {
      useACMEHost = "[your-baseDomain]";
      extraConfig = ''
        reverse_proxy http://127.0.0.1:4000
      '';
    };

    services.caddy.virtualHosts."[your-sub-domain for grafana]" = {
      useACMEHost = "[your-baseDomain]";
      extraConfig = ''
        reverse_proxy http://127.0.0.1:3000
      '';
    };
}
```

## Usage

1. [Generate an access and refresh token](tokens.md)
2. Open the web interface [http://your-ip-address:4000](http://localhost:4000)
3. Enter the access and refresh token on the sign-in page
4. The Grafana dashboards are available at [http://your-ip-address:3000](http://localhost:3000). Log in with the default user `admin` (initial password `admin`) and enter a secure password.
5. In the TeslaMate web interface, go to _Settings → URLs_ and set the _Web App_ and _Dashboards_ URLs, so the links between TeslaMate and Grafana work in both directions.

## Update

To update the running TeslaMate configuration to the latest version, follow: [Upgrading to a new version](../upgrading.mdx)

---

### Installation Tokens (`website/docs/installation/tokens.md`)

---
title: Generating Tokens
sidebar_label: Generating Tokens
---

## Types of tokens

There are two types of tokens:

- Tokens that only work for the unofficial owners API.
- Tokens that only work with the [fleet API](../configuration/api.md).

As by default TeslaMate uses the owners API, this page will show you
how to obtain the first type of token.

## How to generate your own tokens

TeslaMate does not have built-in support for creating the initial token. This
is because the code required to do this requires regular updates to keep it working
properly.

There are multiple apps available to securely generate access tokens yourself, for example:

- [Tesla Auth 0.13.0 or newer (macOS, Linux, Windows)](https://github.com/adriankumpf/tesla_auth/releases/latest)
- [Auth app for Tesla (iOS, macOS)](https://apps.apple.com/us/app/auth-app-for-tesla/id1552058613)

Tesla Auth is packaged in nixpkgs (currently only in nixos-unstable):

```bash
nix shell 'github:nixos/nixpkgs/nixos-unstable#tesla_auth'
```

---

### Integrations Node RED (`website/docs/integrations/Node-RED.md`)

---
title: Node-RED Integration
sidebar_label: Node-RED
---

## Overview

From the Node-RED website:

> Node-RED is a programming tool for wiring together hardware devices, APIs and online services in new and interesting ways.
>
> It provides a browser-based editor that makes it easy to wire together flows using the wide range of nodes in the palette that can be deployed to its runtime in a single-click.

The high-level logic "flow" is coded by wiring "nodes" in the user interface. Low-level logic can be coded in JavaScript. Visit the [Node-RED website](https://nodered.org) for a good introduction on its homepage.

|                    **Node-RED UI**                    |
| :---------------------------------------------------: |
|  |

This integration guide assumes that TeslaMate is deployed on docker and that Node-RED will not be exposed to the internet.
Of course, you can install Node-RED outside of Docker and on another server, if that suits. The integration with TeslaMate is entirely via MQTT. Notifications included in the examples are sent using available Node-RED modules for email and Telegram. Other notifications (e.g. Slack) are relatively simple by replacing the final node in the Notifications flow. One could also integrate with public tools such as IFTT.
Or get really creative and integrate with Alexa or Google Assistant to control the car by voice. :)

Creation of the Telegram bot is not covered in this guide; there is plenty of documentation on the net explaining how to do this (links are provided in the _Requirements_ section below). However, the configuration of the Telgram node in Node-RED is described below.

Included are Node-RED flows with two examples:

- A simple Node-RED dashboard with Car Status and Charge Status panels
- Notification logic for state changes, entering/exiting geofences and time remaining to charge.

|                 **Node-RED Dashboard**                  |
| :-----------------------------------------------------: |
|  |

|          **Example Telegram Notifications**           |
| :---------------------------------------------------: |
|  |

## Requirements

- Teslmate environment, preferably installed in Docker (if you are new to Docker, see Installing Docker and Docker Compose)
- Access by Node-RED to the internet to send notifications
- A mobile device with [Telegram](https://telegram.org/) client installed or use Telegram's browser interface
- your own Telegram Bot, see [Creating a new telegram bot](https://core.telegram.org/bots#6-botfather)
- your own Telegram chat id, see [Get your Telegram chat ID](https://docs.influxdata.com/kapacitor/v1.5/event_handlers/telegram/#get-your-telegram-chat-id)

## Installing Node-RED

Visit the Node-RED [Getting Started](https://nodered.org/docs/getting-started/) page for the various deployment options. If you are using Docker, the following section should suffice to get running.

### Docker Entries

Add the following parameters to your `docker-compose.yml` file. It's assumed that your timezone in set in the .env file's TM_TZ environment variable.

```yaml title="docker-compose.yml"
services:
  node-red:
    image: nodered/node-red:latest
    restart: always
    environment:
      - TZ=${TM_TZ}
    volumes:
      - node-red-data:/data
    ports:
      - "1880:1880"

volumes:
  node-red-data:
```

Build and start the docker container with `docker compose up`. To run the containers in the background, add the `-d` flag:

```bash
docker compose up -d
```

## Node-RED Configuration

There are two flows in the example exports provided. The first flow creates a simple dashboard with some of the MQTT values. The second flow sends notifications to Telegram.
The flow names are "Car Dashboard" and "Notifications".

### Required Modules

After bringing up the Node-RED container the first time, save the following shell script to a file (e.g. named _add-nr-modules.sh_, then run `bash ./add-nr-modules.sh`) to install modules required for the example flows:

```bash title="add-nr-modules.sh"
#!/bin/sh

MODULES="node-red-contrib-calc
node-red-contrib-simpletime
node-red-dashboard
node-red-node-email
node-red-contrib-telegrambot
node-red-node-ui-table"
set -x
for MODULE in $MODULES
do
docker compose exec -T node-red npm install --no-audit --no-update-notifier --no-fund --save --prefix=/data --production $MODULE
done
docker compose stop node-red
docker compose start node-red
```

Note that if your function nodes need additional NPM packages, you can add those into 'MODULES'. You can import those in the function node 'Setup' page, like add module 'linq-js' and import it as variable 'Enumerable'.

### Import Flows

- Download the example JSON file [teslamate-flows.json](./Node-RED/teslamate-flows.json.example)
- Go to Node-RED's hamburger menu in the upper right corner and select `Import`
- Use the `select file to import` button on the pop-up to upload the JSON file.

### MQTT Configuration

If you are using the standard MQTT docker configuration as per the TeslaMate installation guide, after you import the flows Node-RED should automatically connect. Otherwise, open the `teslamate/cars/1/#` node in the Car Dashboard flow, select the pencil icon next to the `Server` field in the panel, then edit the MQTT server's parameters. Click Update, Done and Deploy.

### Telegram Configuration

To enter your Telegram Bot's parameters:

- Edit the `Status Messages` Telegram node in the Notifications flow, then select the pencil icon next to the `Bot` name.
- Replace the `Bot-Name` field with the name of your Telegram bot
- Fill the `Token` field with the value that you copied from setting up your bot.

|                     **Telegram configuration pop-up**                      |
| :------------------------------------------------------------------------: |
|  |

- Click `Update`, then `Done`
- Edit the `Format messages` node in the Notifications flow
- Replace the value for `chatId` with the chatId that you obtained setting up the bot.
- Click `Done`
- Click `Deploy` to re-deploy your flows. "Connected" should now display beneath the `Status Messages` node.

### Email configuration

If you want to quickly try out this implementation without Telegram, you can simply remove the connection between the `Format Messages` and `Status Messages` nodes, then connect `Format Messages` with the `email` node. Edit the email node to set your parameters to send emails. After you re-deploy you should get at least one message as per the note below.

### Notes

- When you re-deploy your flows, a _Tesla entered Geofence ..._ message and a _Tesla Driver is present:_ notification may be sent. Some might consider this a bug. Or a test that the notification channel is working. :)

---

### Integrations Home Assistant (`website/docs/integrations/home_assistant.md`)

---
title: Home Assistant Integration
sidebar_label: Home Assistant
---

## Introduction

Whilst Home Assistant provides an official component for Tesla vehicles, the component has not been updated recently, and does not have the sophistication of TeslaMate's polling mechanism, resulting in the component's default values keeping the vehicle awake and draining the battery.

The ultimate goal of this guide is to consume as much of the TeslaMate polling data as possible to replace the majority of the official Tesla component's polling functionality.

If your intention is to only use read-only sensor values, those provided by TeslaMate via MQTT are sufficient, and you do not need to utilise the official Tesla component. If however you would like to be able to write values to the Tesla API (Lock/Unlock Doors or automate Climate), there is a solution which involves configuring an extremely high polling interval for the Tesla component and using automation to populate the values from the TeslaMate MQTT parameters.

### Screenshots

import useBaseUrl from '@docusaurus/useBaseUrl';

<img alt="HASS Screenshot" src={useBaseUrl('img/hass-dashboard.png')} />

### Current Status

- Sensors: All sensors exposed by the Tesla component are available
- Locks: Not implemented
- Climate: Not implemented

## MQTT Discovery (automatic configuration)

TeslaMate can publish [Home Assistant MQTT discovery](https://www.home-assistant.io/integrations/mqtt/#mqtt-discovery) payloads, so the entities below are created automatically and you no longer need to maintain `mqtt_sensors.yaml`.

Enable it with the following environment variables (see [Environment variables](../configuration/environment_variables.md)):

| Variable                               | Description                                                                                    | Default         |
| -------------------------------------- | ---------------------------------------------------------------------------------------------- | --------------- |
| `MQTT_HOME_ASSISTANT_DISCOVERY`        | Set to `true` to enable discovery.                                                             | `false`         |
| `MQTT_HOME_ASSISTANT_DISCOVERY_URL`    | TeslaMate URL surfaced in the discovered device panel (e.g. `https://teslamate.example.com/`). | _none_          |
| `MQTT_HOME_ASSISTANT_DISCOVERY_PREFIX` | Discovery topic prefix. Must match Home Assistant's `discovery_prefix` setting.                | `homeassistant` |

When enabled, TeslaMate publishes one retained device discovery payload per
vehicle to `<discovery_prefix>/device/<node>/config` on the first vehicle
summary. The payload contains all of the vehicle's entities, and `<node>` is
`teslamate_<car_id>`. If
`MQTT_NAMESPACE` is set, it is inserted after `teslamate_` (e.g.
`teslamate_<namespace>_<car_id>`), so multiple TeslaMate instances sharing a
broker do not collide on the same discovery topics. The device is grouped
under the `teslamate_car_<car_id>` identifier (likewise namespace-scoped), and
the entity IDs match those produced by the manual `mqtt_sensors.yaml` below.

On the first vehicle summary after each startup, TeslaMate clears every retained
topic from its former per-entity discovery format, waits for Home Assistant to
process the removals, and then publishes one complete device discovery payload.
For installations already using device discovery, repeating this sequence is
state-idempotent but not silent. MQTT forwards each zero-byte retained publish
to Home Assistant even when the legacy retained topic is already absent, so
Home Assistant logs one harmless "conflicting MQTT discovery message" warning
for each of the 62 legacy topics per vehicle after every TeslaMate restart.
These warnings do not change or remove any existing entity, and the retained
device payload is unchanged.

This cleanup does not use Home Assistant's discovery migration protocol. As a
result, entity registry settings and customizations from the former per-entity
format are not preserved when upgrading directly from TeslaMate 4.1.x.

:::note

The `unique_id`s of the discovered entities match those of the manual
`mqtt_sensors.yaml`, so enabling discovery while the manual configuration is
still active will produce duplicate-ID errors in Home Assistant. Remove the
manual `mqtt: !include mqtt_sensors.yaml` section from `configuration.yaml`
(and the entities it created) before enabling discovery.

:::

On startup, discovery configs are also cleared for cars that are no longer
tracked, e.g. because they were removed from the Tesla account or because
logging was disabled, so their entities are removed from Home Assistant.

While discovery is disabled, TeslaMate publishes a zero-byte retained payload
to the device discovery topic and to each of the 62 legacy topics of every
vehicle on each startup, so the entities of a previously enabled discovery are
removed from Home Assistant. Nothing is left on the broker, but clients
subscribed to `<discovery_prefix>/#` see these empty messages after every
TeslaMate restart, even if discovery was never enabled.

The cleanup runs on every startup because TeslaMate cannot know whether
discovery configs exist: MQTT offers no reliable way to learn that all
retained messages have been received, and storing what was published would be
a second state that can drift from the broker, e.g. after restoring a database
backup. Repeating the cleanup is harmless, and a cleanup that failed, e.g.
because the broker was unreachable, is simply retried on the next start.

The discovered entities cover the same set of `teslamate/cars/<id>/...` topics
as the manual `mqtt_sensors.yaml` below.

:::note

Configs are only cleared at startup. A car removed while TeslaMate is running
keeps its entities until the next restart, and changing
`MQTT_HOME_ASSISTANT_DISCOVERY_PREFIX` does not clean up topics published under
the previous prefix.

:::

## Configuration

:::warning[Legacy configuration]

Prefer [MQTT discovery](#mqtt-discovery-automatic-configuration) for new installations. The manual YAML remains available for older Home Assistant versions and custom setups, but it is frozen and will not receive new sensors.

:::

The following configurations assume a car ID of 1 (`teslamate/cars/1`). It usually starts at 1, but it can be different if you have multiple cars in TeslaMate for example.

### configuration.yaml

Proximity sensors allow us to calculate the proximity of the Tesla `device_tracker` to defined zones. This can be useful for:

- Automatic Garage Door opening when you arrive home
- Notifications when the vehicle is arriving

```yml title="configuration.yaml"
automation: !include automation.yaml

proximity:
  home_tesla:
    zone: home
    devices:
      - device_tracker.tesla_location
    tolerance: 10
    unit_of_measurement: km

tesla:
  username: !secret tesla_username
  password: !secret tesla_password
  scan_interval: 3600

mqtt: !include mqtt_sensors.yaml
```

### mqtt_sensors.yaml (mqtt: section of configuration.yaml)

Don't forget to replace `<teslamate url>`, `<your tesla model>` and `<your tesla name>` with correct corresponding values.

```
/* Detailed source-code truncated for AI context efficiency. */
```

### ui-lovelace.yaml

The below is the Lovelace UI configuration used to make the example screenshot above. You will obviously want to configure this to your liking, however the example contains all of the sensors and values presented via MQTT and could be used as the basis of UI configuration.

```
/* Detailed source-code truncated for AI context efficiency. */
```

## Useful Automations

The below automations leverage TeslaMate MQTT topics to provide some useful automations

### Garage Door Automation based on Tesla location

This automation triggers when the Tesla transitions from not_home to home. This means that the vehicle would have had to have been outside of the home zone previously, and returned home. You may want to add conditions here to improve accuracy, such as time of day.

```yml title="automation.yaml"
- alias: Open garage if car returns home
  initial_state: on
  trigger:
    - platform: state
      entity_id: device_tracker.tesla_location
      from: "not_home"
      to: "home"
  action:
    - service: switch.turn_on
      entity_id: switch.garage_door_switch
```

### Notification for Doors and Windows left open

The following set of automations and scripts will detect when a Tesla door, frunk, trunk or window is left open. The script will notify you after the defined time period (by default, 5 minutes). If you would like to customize how the notification is performed, you can edit the `notify_tesla_open` script which is called by all of the four notifications.

By default, the script will repeatedly notify every 5 minutes. Remove the recursive `script.turn_on` sequence in the `notify_tesla_open` script if you'd only like to be informed once.

We add the random 30 second interval after each notification to avoid clobbering the notification script when we have multiple things open at once.
For example, opening the door will open the door and the window. If we don't delay the calls, we will only get a message about the window (as it is the last call to the script) and if we then close the window, we won't get notifications about other things left open. This results in more notifications but less chance on missing out on knowing something was left open.

#### automation.yaml

```yml title="automation.yaml"
- alias: Set timer if TeslaMate reports something is open to alert us
  initial_state: on
  trigger:
    - platform: mqtt
      topic: teslamate/cars/1/windows_open
      payload: "true"
    - platform: mqtt
      topic: teslamate/cars/1/doors_open
      payload: "true"
    - platform: mqtt
      topic: teslamate/cars/1/trunk_open
      payload: "true"
    - platform: mqtt
      topic: teslamate/cars/1/frunk_open
      payload: "true"
  action:
    - service: script.turn_on
      data_template:
        entity_id: script.notify_tesla_{{trigger.topic.split('/')[3]}}

- alias: Cancel notification if said door/window is closed
  initial_state: on
  trigger:
    - platform: mqtt
      topic: teslamate/cars/1/windows_open
      payload: "false"
    - platform: mqtt
      topic: teslamate/cars/1/doors_open
      payload: "false"
    - platform: mqtt
      topic: teslamate/cars/1/trunk_open
      payload: "false"
    - platform: mqtt
      topic: teslamate/cars/1/frunk_open
      payload: "false"
  action:
    - service: script.turn_off
      data_template:
        entity_id: script.notify_tesla_{{trigger.topic.split('/')[3]}}
```

#### script.yaml

```
/* Detailed source-code truncated for AI context efficiency. */
```

---

### Integrations Mqtt (`website/docs/integrations/mqtt.md`)

---
title: MQTT Integration
sidebar_label: MQTT
---

The MQTT function within TeslaMate allows useful values to be published to an MQTT broker. This is useful in allowing other automation platforms to consume data from TeslaMate.

## MQTT Topics

Vehicle data will be published to the following topics:

| Topic                                                  | Example                                                                                     | Description                                                                           |
| ------------------------------------------------------ | ------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
| `teslamate/cars/$car_id/display_name`                  | Blue Thunder                                                                                | Vehicle Name                                                                          |
| `teslamate/cars/$car_id/state`                         | asleep                                                                                      | Status of the vehicle (e.g. `online`, `asleep`, `charging`)                           |
| `teslamate/cars/$car_id/since`                         | 2019-02-29T23:00:07Z                                                                        | Date of the last status change                                                        |
| `teslamate/cars/$car_id/healthy`                       | true                                                                                        | Health status of the logger for that vehicle                                          |
| `teslamate/cars/$car_id/version`                       | 2019.32.12.2                                                                                | Software Version                                                                      |
| `teslamate/cars/$car_id/update_available`              | false                                                                                       | Indicates if a software update is available                                           |
| `teslamate/cars/$car_id/update_version`                | 2019.32.12.3                                                                                | Software version of the available update                                              |
| `teslamate/cars/$car_id/download_perc`                 | 100                                                                                         | Download progress of the available update in percent                                  |
| `teslamate/cars/$car_id/install_perc`                  | 42                                                                                          | Installation progress of the update in percent                                        |
|                                                        |                                                                                             |                                                                                       |
| `teslamate/cars/$car_id/model`                         | 3                                                                                           | Either "S", "3", "X" or "Y"                                                           |
| `teslamate/cars/$car_id/trim_badging`                  | P100D                                                                                       | Trim badging                                                                          |
| `teslamate/cars/$car_id/exterior_color`                | DeepBlue                                                                                    | The exterior color                                                                    |
| `teslamate/cars/$car_id/wheel_type`                    | Pinwheel18                                                                                  | The wheel type                                                                        |
| `teslamate/cars/$car_id/spoiler_type`                  | None                                                                                        | The spoiler type                                                                      |
|                                                        |                                                                                             |                                                                                       |
| `teslamate/cars/$car_id/geofence`                      | 🏡 Home                                                                                     | The name of the Geo-fence, if one exists at the current position                      |
|                                                        |                                                                                             |                                                                                       |
| `teslamate/cars/$car_id/latitude`                      | 35.278131                                                                                   | DEPRECATED: Last reported car latitude                                                |
| `teslamate/cars/$car_id/longitude`                     | 29.744801                                                                                   | DEPRECATED: Last reported car longitude                                               |
| `teslamate/cars/$car_id/location`                      | <pre lang="json">\{<br /> "latitude": 35.278131,<br /> "longitude": 29.744801<br />\}</pre> | Last reported car location (json blob)                                                |
| `teslamate/cars/$car_id/shift_state`                   | D                                                                                           | Current/Last Shift State (D/N/R/P)                                                    |
| `teslamate/cars/$car_id/power`                         | -9                                                                                          | Current battery power in watts. Positive value on discharge, negative value on charge |
| `teslamate/cars/$car_id/speed`                         | 12                                                                                          | Current Speed in km/h                                                                 |
| `teslamate/cars/$car_id/heading`                       | 340                                                                                         | Last reported car direction                                                           |
| `teslamate/cars/$car_id/elevation`                     | 70                                                                                          | Current elevation above sea level in meters                                           |
|                                                        |                                                                                             |                                                                                       |
| `teslamate/cars/$car_id/locked`                        | true                                                                                        | Indicates if the car is locked                                                        |
| `teslamate/cars/$car_id/sentry_mode`                   | false                                                                                       | Indicates if Sentry Mode is active                                                    |
| `teslamate/cars/$car_id/windows_open`                  | false                                                                                       | Indicates if any of the windows are open                                              |
| `teslamate/cars/$car_id/driver_front_window_open`      | false                                                                                       | Indicates if the driver-side front window is open                                     |
| `teslamate/cars/$car_id/driver_rear_window_open`       | false                                                                                       | Indicates if the driver-side rear window is open                                      |
| `teslamate/cars/$car_id/passenger_front_window_open`   | false                                                                                       | Indicates if the passenger-side front window is open                                  |
| `teslamate/cars/$car_id/passenger_rear_window_open`    | false                                                                                       | Indicates if the passenger-side rear window is open                                   |
| `teslamate/cars/$car_id/doors_open`                    | false                                                                                       | Indicates if any of the doors are open                                                |
| `teslamate/cars/$car_id/driver_front_door_open`        | false                                                                                       | Indicates if the driver-side front door is open                                       |
| `teslamate/cars/$car_id/driver_rear_door_open`         | false                                                                                       | Indicates if the driver-side rear door is open                                        |
| `teslamate/cars/$car_id/passenger_front_door_open`     | false                                                                                       | Indicates if the passenger-side front door is open                                    |
| `teslamate/cars/$car_id/passenger_rear_door_open`      | false                                                                                       | Indicates if the passenger-side rear door is open                                     |
| `teslamate/cars/$car_id/sun_roof_state`                | open                                                                                        | Current sunroof state                                                                 |
| `teslamate/cars/$car_id/sun_roof_installed`            | true                                                                                        | Indicates if the vehicle has a sunroof                                                |
| `teslamate/cars/$car_id/sun_roof_percent_open`         | 80                                                                                          | Current sunroof open percentage                                                       |
| `teslamate/cars/$car_id/trunk_open`                    | false                                                                                       | Indicates if the trunk is open                                                        |
| `teslamate/cars/$car_id/frunk_open`                    | false                                                                                       | Indicates if the frunk is open                                                        |
| `teslamate/cars/$car_id/is_user_present`               | false                                                                                       | Indicates if a user is present in the vehicle                                         |
|                                                        |                                                                                             |                                                                                       |
| `teslamate/cars/$car_id/is_climate_on`                 | true                                                                                        | Indicates if the climate control is on                                                |
| `teslamate/cars/$car_id/inside_temp`                   | 20.8                                                                                        | Inside Temperature in °C                                                              |
| `teslamate/cars/$car_id/outside_temp`                  | 18.4                                                                                        | Temperature in °C                                                                     |
| `teslamate/cars/$car_id/is_preconditioning`            | false                                                                                       | Indicates if the vehicle is being preconditioned                                      |
|                                                        |                                                                                             |                                                                                       |
| `teslamate/cars/$car_id/odometer`                      | 1653                                                                                        | Car odometer in km                                                                    |
| `teslamate/cars/$car_id/est_battery_range_km`          | 372.5                                                                                       | Estimated Range in km                                                                 |
| `teslamate/cars/$car_id/rated_battery_range_km`        | 401.63                                                                                      | Rated Range in km                                                                     |
| `teslamate/cars/$car_id/ideal_battery_range_km`        | 335.79                                                                                      | Ideal Range in km                                                                     |
|                                                        |                                                                                             |                                                                                       |
| `teslamate/cars/$car_id/battery_level`                 | 88                                                                                          | Battery Level Percentage                                                              |
| `teslamate/cars/$car_id/usable_battery_level`          | 85                                                                                          | Usable battery level percentage                                                       |
| `teslamate/cars/$car_id/plugged_in`                    | true                                                                                        | If car is currently plugged into a charger                                            |
| `teslamate/cars/$car_id/charging_state`                | Charging                                                                                    | The cars charging state (Charging, Disconnected, Stopped, NoPower, Complete)          |
| `teslamate/cars/$car_id/charge_energy_added`           | 5.06                                                                                        | Last added energy in kWh                                                              |
| `teslamate/cars/$car_id/charge_limit_soc`              | 90                                                                                          | Charge Limit Configured in Percentage                                                 |
| `teslamate/cars/$car_id/charge_port_door_open`         | true                                                                                        | Indicates if the charger door is open                                                 |
| `teslamate/cars/$car_id/charger_actual_current`        | 2.05                                                                                        | Current amperage supplied by charger                                                  |
| `teslamate/cars/$car_id/charger_phases`                | 3                                                                                           | Number of charger power phases (1-3)                                                  |
| `teslamate/cars/$car_id/charger_power`                 | 48.9                                                                                        | Charger Power                                                                         |
| `teslamate/cars/$car_id/charger_voltage`               | 240                                                                                         | Charger Voltage                                                                       |
| `teslamate/cars/$car_id/charge_current_request`        | 40                                                                                          | How many amps the car wants                                                           |
| `teslamate/cars/$car_id/charge_current_request_max`    | 40                                                                                          | How many amps the car can have                                                        |
| `teslamate/cars/$car_id/scheduled_charging_start_time` | 2019-02-29T23:00:07Z                                                                        | Start time of the scheduled charge                                                    |
| `teslamate/cars/$car_id/time_to_full_charge`           | 1.83                                                                                        | Hours remaining to full charge                                                        |
| `teslamate/cars/$car_id/tpms_pressure_fl`              | 2.9                                                                                         | Tire pressure measure in BAR, front left tire                                         |
| `teslamate/cars/$car_id/tpms_pressure_fr`              | 2.8                                                                                         | Tire pressure measure in BAR, front right tire                                        |
| `teslamate/cars/$car_id/tpms_pressure_rl`              | 2.9                                                                                         | Tire pressure measure in BAR, rear left tire                                          |
| `teslamate/cars/$car_id/tpms_pressure_rr`              | 2.8                                                                                         | Tire pressure measure in BAR, rear right tire                                         |
| `teslamate/cars/$car_id/tpms_soft_warning_fl`          | true                                                                                        | Indicates if the Tire pressure measure is soft warning, front left tire               |
| `teslamate/cars/$car_id/tpms_soft_warning_fr`          | false                                                                                       | Indicates if the Tire pressure measure is soft warning, front right tire              |
| `teslamate/cars/$car_id/tpms_soft_warning_rl`          | false                                                                                       | Indicates if the Tire pressure measure is soft warning, rear left tire                |
| `teslamate/cars/$car_id/tpms_soft_warning_rr`          | false                                                                                       | Indicates if the Tire pressure measure is soft warning, rear right tire               |
| `teslamate/cars/$car_id/active_route_destination`      | Home                                                                                        | DEPRECATED: Navigation destination name (or "nil")                                    |
| `teslamate/cars/$car_id/active_route_latitude`         | 35.278131                                                                                   | DEPRECATED: Navigation destination latitude (or "nil")                                |
| `teslamate/cars/$car_id/active_route_longitude`        | 29.744801                                                                                   | DEPRECATED: Navigation destination longitude (or "nil")                               |
| `teslamate/cars/$car_id/active_route`                  | _See below_                                                                                 | Navigation details (json blob)                                                        |
| `teslamate/cars/$car_id/center_display_state`          | 0                                                                                           | Center Display State                                                                  |
| `teslamate/cars/$car_id/service_mode`                  | false                                                                                       | Whether Service Mode is active or not                                                 |

:::note
`$car_id` usually starts at 1
:::

:::note
A topic is published empty when the car reports no value for it, e.g. `speed` and `shift_state` while the car is switched off; `location` is never published empty. A topic the car has not reported since TeslaMate started is not published, so its retained value stays. While TeslaMate runs, the `odometer` never decreases and is never published empty.
:::

### `active_route` payload examples

Routing to a destination.

```json
{
  "destination": "Home",
  "energy_at_arrival": 73,
  "miles_to_arrival": 6.485299,
  "minutes_to_arrival": 23.466667,
  "traffic_minutes_delay": 0.0,
  "location": {
    "latitude": 35.278131,
    "longitude": 29.744801
  },
  "error": null
}
```

Not routing to a destination.

```json
{
  "error": "No active route available"
}
```

---

### Maintenance Backup (`website/docs/maintenance/backup.mdx`)

---
title: Backup
sidebar_label: Backup
---

:::warning
**For better protection, the created backup should be transferred off the host to an independent storage location, ensuring it cannot be overwritten or lost in the event of a host failure.**
:::

:::note
If you are using `docker-compose`, you are using Docker Compose v1, which has been deprecated. Docker Compose commands refer to Docker Compose v2. Consider upgrading your docker setup, see [Migrate to Compose V2](https://docs.docker.com/compose/migrate/)
:::

## Backup

Create backup file `teslamate.bck`:

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

<Tabs
defaultValue="dockerCompose"
groupId="type"
values={[
    { label: 'Docker Compose', value: 'dockerCompose', },
    { label: 'NixOS', value: 'nixos', },
]}>
<TabItem value="dockerCompose">

```bash
docker compose exec -T database pg_dump -U teslamate teslamate > ./teslamate.bck
```

:::note
`-T` is important if you add this line a crontab or the backup will not work because docker will generate this error `the input device is not a TTY`
:::

:::note
Be absolutely certain to move the `teslamate.bck` file to another safe location, as you may lose that backup file if you use a docker-compose GUI to upgrade your teslamate configuration. Some GUIs delete the folder that holds the `docker-compose.yml` when updating.
:::

:::note
If you get the error `No such service: database`, update your _docker-compose.yml_ or use `db` instead of `database` in the above command.
:::

:::note
If you changed `TM_DB_USER` in the .env file from one of the advanced guides, make sure to replace the first instance of `teslamate` to the value of `TM_DB_USER` in the above command.
:::

</TabItem>
<TabItem value="nixos">

You can use the idiomatic backup script:

```bash
teslamate-backup teslamate_$(date +%Y%m%d-%H%M).bck
```

</TabItem>
</Tabs>

---

### Maintenance Manually Fixing Data (`website/docs/maintenance/manually_fixing_data.mdx`)

---
title: Manually fixing data
---

:::note
If you are using `docker-compose`, you are using Docker Compose v1, which has been deprecated. Docker Compose commands refer to Docker Compose v2. Consider upgrading your docker setup, see [Migrate to Compose V2](https://docs.docker.com/compose/migrate/)
:::

## Get the ID

First you need to find out the ID of the drive or charge:

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

<Tabs
defaultValue="drive"
groupId="type"
values={[
    { label: 'Drive', value: 'drive', },
    { label: 'Charge', value: 'charge', },
]}>
<TabItem value="drive">

- Open the `Drives` dashboard and click on the start date of the drive.
- The URL will contain the drive ID, for example `&var-drive_id=9999`.

</TabItem>
<TabItem value="charge">

- Open the `Charges` dashboard and click on the start date of the charge.
- The URL will contain the charge id, for example `&var-charging_process_id=9999`.

</TabItem>
</Tabs>

## Terminate a drive or charge

If for some reason a drive or charge hasn't been fully recorded, for example due to a bug or an unexpected restart, you can terminate it manually. Among other things, this assigns an end date to the drive/charge.

Replace `9999` with the actual ID then run the command while the TeslaMate container is running:

<Tabs
defaultValue="drive"
groupId="type"
values={[
    { label: 'Drive', value: 'drive', },
    { label: 'Charge', value: 'charge', },
    { label: 'Drive (NixOS)', value: 'drive-nixos', },
    { label: 'Charge (NixOS)', value: 'charge-nixos', },
]}>
<TabItem value="drive">

```bash
docker compose exec teslamate bin/teslamate rpc \
    "TeslaMate.Repo.get!(TeslaMate.Log.Drive, 9999) |> TeslaMate.Log.close_drive()"
```

</TabItem>
<TabItem value="charge">

```bash
docker compose exec teslamate bin/teslamate rpc \
    "TeslaMate.Repo.get!(TeslaMate.Log.ChargingProcess, 9999) |> TeslaMate.Log.complete_charging_process()"
```

</TabItem>
<TabItem value="drive-nixos">

```bash
teslamate-close-drive 9999
```

</TabItem>
<TabItem value="charge-nixos">

```bash
teslamate-close-charge 9999
```

</TabItem>
</Tabs>

## Delete a drive or charge

If for some reason a drive or charge was recorded incorrectly, you can delete it.

<Tabs
defaultValue="drive"
groupId="type"
values={[
    { label: 'Drive', value: 'drive', },
    { label: 'Charge', value: 'charge', },
    { label: 'Drive (NixOS)', value: 'drive-nixos', },
    { label: 'Charge (NixOS)', value: 'charge-nixos', },
]}>
<TabItem value="drive">

1.  Attach to the **running** database container:

    ```bash
    docker compose exec database psql teslamate teslamate
    ```

    :::note
    If you get the error `No such service: database`, update your _docker-compose.yml_ or use `db` instead of `database` in the above command.
    :::

2.  Afterwards replace `9999` with the actual ID then run the query:

                ```sql
                DELETE FROM drives WHERE id = 9999;
                ```

</TabItem>
<TabItem value="charge">

1.  Attach to the **running** database container:

    ```bash
    docker compose exec database psql teslamate teslamate
    ```

    :::note
    If you get the error `No such service: database`, update your _docker-compose.yml_ or use `db` instead of `database` in the above command.
    :::

2.  Afterwards replace `9999` with the actual ID then run the query:

    ```sql
    DELETE FROM charging_processes WHERE id = 9999;
    ```

</TabItem>

<TabItem value="drive-nixos">

You can use the idiomatic maintenance script:

    ```bash
    teslamate-delete-drive 9999
    ```

</TabItem>
<TabItem value="charge-nixos">

You can use the idiomatic maintenance script:

    ```bash
    teslamate-delete-charge 9999
    ```

</TabItem>
</Tabs>

## Remove a vehicle from the database

**NOTE:** Always [backup](backup.mdx) your data before performing any database changes.

1. Connect to your running TeslaMate database

   ```bash
   docker compose exec database psql teslamate teslamate
   ```

   :::note
   If you get the error `No such service: database`, update your _docker-compose.yml_ or use `db` instead of `database` in the above command.
   :::

2. Identify the right car ID in the database to remove

```sql
SELECT id, vin FROM cars;
```

3. Based upon the output, run the following command replacing `num` with the ID from the previous command.

```sql
DELETE FROM cars WHERE id = num;
DELETE FROM car_settings WHERE id = num;
DELETE FROM charging_processes WHERE car_id = num;
DELETE from charges WHERE charging_process_id in (select id from charging_processes where car_id = num);
DELETE FROM drives WHERE car_id = num;
DELETE FROM positions WHERE car_id = num;
DELETE FROM states WHERE car_id = num;
DELETE FROM updates WHERE car_id = num;
```

## Reindex Database

**NOTE:** If your database experiences a lot of updates or deletions, like importing data from other sources or deleting a loaner car or some other similar situation, you might encounter index bloat, which can degrade performance. In such cases, reindexing could be beneficial.

In summary, you don't necessarily need to run REINDEX periodically unless your database workload involves significant amounts of updates and deletions, if so, you may you may proceed as indicated in the following steps:

1. Connect to your running TeslaMate database

   ```bash
   docker compose exec -T database psql teslamate teslamate
   ```

   :::note
   If you get the error `No such service: database`, update your _docker-compose.yml_ or use `db` instead of `database` in the above command.
   :::

2. Run the following script (copy and paste)

   ```sql
   REINDEX DATABASE teslamate
   ```

3. Exit the prompt by typing:

   ```bash
   \q  (or press CTRL + C)
   ```

---

### Maintenance Restore (`website/docs/maintenance/restore.mdx`)

---
title: Restore
sidebar_label: Restore data from Backup
---

:::note
If you are using `docker-compose`, you are using Docker Compose v1, which has been deprecated. Docker Compose commands refer to Docker Compose v2. Consider upgrading your docker setup, see [Migrate to Compose V2](https://docs.docker.com/compose/migrate/)
:::

## Restore

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

<Tabs
defaultValue="dockerCompose"
groupId="type"
values={[
    { label: 'Docker Compose', value: 'dockerCompose', },
    { label: 'NixOS', value: 'nixos', },
]}>
<TabItem value="dockerCompose">

:::note
Replace the default `teslamate` value below with the value defined in the .env file if you have one (TM_DB_USER and TM_DB_NAME)
:::

```bash
# Stop the teslamate container to avoid write conflicts
docker compose stop teslamate

# Drop existing data and reinitialize (Don't forget to replace first teslamate if using different TM_DB_USER)
docker compose exec -T database psql -U teslamate teslamate << .
DROP SCHEMA IF EXISTS public CASCADE;
DROP SCHEMA IF EXISTS private CASCADE;
CREATE SCHEMA public;
CREATE EXTENSION cube WITH SCHEMA public;
CREATE EXTENSION earthdistance WITH SCHEMA public;
.

# Restore
docker compose exec -T database psql -U teslamate -d teslamate < teslamate.bck

# Restart the teslamate container
docker compose start teslamate
```

</TabItem>
<TabItem value="nixos">

You can use the idiomatic restore script, for example:

```bash
teslamate-restore teslamate_20250805-1622.bck
```

</TabItem>
</Tabs>

---

### Maintenance Upgrading Postgres (`website/docs/maintenance/upgrading_postgres.md`)

---
title: Upgrading PostgreSQL to a new major version
sidebar_label: Upgrading PostgreSQL
---

1. Create a [backup](backup.mdx)
2. Stop all TeslaMate containers

   ```bash
   docker compose down
   ```

3. Delete the database volume. **Be careful**, this will delete all your previously recorded data! Make sure that your backup can be restored before you start.

   ```bash
   docker volume rm "$(basename "$PWD")_teslamate-db"
   ```

4. Change the postgres version and ensure your volume mount is [configured correctly](https://hub.docker.com/_/postgres#pgdata) in docker-compose.yml and start the container

   ```yml {2}
   database:
     image: postgres:18-trixie
     ...
     volumes:
       - teslamate-db:/var/lib/postgresql
   ```

   ```bash
   docker compose up -d database
   ```

5. [Restore](restore.mdx) the backup

---

### Installation Unsupported Debian (`website/docs/installation/unsupported/debian.md`)

---
title: Manual install - Debian (no support)
sidebar_label: Manual - Debian (no support)
---

This document provides the necessary steps for installation of TeslaMate on a vanilla Debian or Ubuntu system. The **recommended and most straightforward installation approach is through the use of [Docker](../docker.md)**, however this walkthrough provides the necessary steps for manual installation in an aptitude (Debian/Ubuntu) environment.

## Requirements

Click on the following items to view detailed installation steps.

Note that in very recent distributions, you might have the required versions already packaged. However, the contents or naming of the Debian/Ubuntu packages might slightly differ than the ones from upstream, so you might need to install extra packages or do other tweaks.

<details>
  <summary>Postgres (v16.7+, v17.3+ or v18.0+)</summary>

Either upstream:

```bash
wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -
echo "deb http://apt.postgresql.org/pub/repos/apt/ `lsb_release -cs`-pgdg main" | sudo tee /etc/apt/sources.list.d/pgdg.list
sudo apt-get update
sudo apt-get install -y postgresql-18 postgresql-client-18
```

Source: [postgresql.org/download](https://www.postgresql.org/download/)

Or if you run a recent enough distribution (e.g. Debian Trixie:):

```bash
sudo apt install postgresql-17 postgresql-client-17
```

</details>

<details>
  <summary>Elixir (v1.19+ on Erlang/OTP 28+)</summary>

The Erlang and Elixir packages of Debian stable are too old, so install both with [mise](https://mise.jdx.dev/). On Ubuntu 22.04 and 24.04 mise downloads a precompiled Erlang/OTP; on Debian it compiles Erlang/OTP from source, which takes a while.

```bash
sudo apt install -y extrepo
sudo extrepo enable mise
sudo apt update
sudo apt install -y mise build-essential libncurses-dev libssl-dev openssl curl
echo 'eval "$(mise activate bash)"' >> ~/.bashrc && source ~/.bashrc
mise use --global erlang@29 elixir@1.20.3-otp-29
```

Run the [compile steps](#compile-elixir-project) as the same user, so `mix` is on the `PATH`.

Source: [mise.jdx.dev/lang/elixir](https://mise.jdx.dev/lang/elixir.html)

</details>

<details>
  <summary>Grafana (v13.2.3+)</summary>

```bash
sudo apt-get install -y apt-transport-https software-properties-common
sudo add-apt-repository "deb https://apt.grafana.com stable main"
wget -q -O - https://apt.grafana.com/gpg-full.key | sudo apt-key add -
sudo apt-get update
sudo apt-get install -y grafana
sudo systemctl start grafana-server
sudo systemctl enable grafana-server.service # to start Grafana at boot time
```

Source: [grafana.com/docs/installation](https://grafana.com/docs/grafana/latest/installation/)

[Import the Grafana dashboards](#import-grafana-dashboards) after [cloning the TeslaMate git repository](#clone-teslamate-git-repository).

</details>

<details>
  <summary>An MQTT Broker (e.g. Mosquitto)</summary>

```bash
sudo apt-get install -y mosquitto
```

Source: [mosquitto.org/download](https://mosquitto.org/download/)

</details>

<details>
  <summary>Node.js (v22+)</summary>

Either from upstream:

```bash
curl -fsSL https://deb.nodesource.com/setup_22.x | sudo bash -
sudo apt-get install -y nodejs
```

Source: [nodejs.org/en/download/package-manager](https://nodejs.org/en/download/package-manager/all#debian-and-ubuntu-based-linux-distributions)

Or if you run a recent enough distribution (e.g. Debian Trixie:):

```bash
sudo apt install nodejs npm
```

</details>

## Clone TeslaMate git repository

The following command will clone the source files for the TeslaMate project. This should be run in an appropriate directory within which you would like to install TeslaMate. You should also record this path and provide them to the startup scripts proposed at the end of this guide.

```bash
cd /usr/src

git clone https://github.com/teslamate-org/teslamate.git
cd teslamate

git checkout $(git describe --tags `git rev-list --tags --max-count=1`) # Checkout the latest stable version
```

## Create PostgreSQL database

The following commands will create a database called `teslamate` on the PostgreSQL database server, and a user called `teslamate`. When creating the `teslamate` user, you will be prompted to enter a password for the user interactively. This password should be recorded and provided as an environment variable in the startup script at the end of this guide.

```console
sudo -u postgres psql
postgres=# create database teslamate;
postgres=# create user teslamate with encrypted password 'your_secure_password_here';
postgres=# grant all privileges on database teslamate to teslamate;
postgres=# ALTER USER teslamate WITH SUPERUSER;
postgres=# \q
```

_Note: The superuser privileges can be revoked after running the initial database migrations._

## Compile Elixir Project

```bash
cd elixir
mix local.hex --force; mix local.rebar --force

mix deps.get --only prod
npm install --prefix ./assets && npm run deploy --prefix ./assets

MIX_ENV=prod mix do phx.digest, release --overwrite
```

### Set your system locale

You may need to set your system locale. If you get an error when running the TeslaMate service which indicates that you don't have a UTF-8 capable system locale set, run the following commands to set the locale on your system:

```bash
sudo locale-gen en_US.UTF-8
sudo localectl set-locale LANG=en_US.UTF-8
```

## Starting TeslaMate at boot time

import Tabs from "@theme/Tabs";
import TabItem from "@theme/TabItem";

<Tabs
defaultValue="systemd"
values={[
{ label: 'systemd', value: 'systemd', },
{ label: 'screen', value: 'screen', },
]}>
<TabItem value="systemd">

Create a systemd service at `/etc/systemd/system/teslamate.service`:

```ini
[Unit]
Description=TeslaMate
After=network.target
After=postgresql.service

[Service]
Type=simple
# User=username
# Group=groupname

Restart=on-failure
RestartSec=5

Environment="HOME=/usr/src/teslamate"
Environment="LANG=en_US.UTF-8"
Environment="LC_CTYPE=en_US.UTF-8"
Environment="TZ=Europe/Berlin"
Environment="PORT=4000"
Environment="ENCRYPTION_KEY=your_secure_encryption_key_here"
Environment="DATABASE_USER=teslamate"
Environment="DATABASE_PASS=#your secure password!
Environment="DATABASE_NAME=teslamate"
Environment="DATABASE_HOST=127.0.0.1"
Environment="MQTT_HOST=127.0.0.1"

WorkingDirectory=/usr/src/teslamate

ExecStartPre=/usr/src/teslamate/elixir/_build/prod/rel/teslamate/bin/teslamate eval "TeslaMate.Release.migrate"
ExecStart=/usr/src/teslamate/elixir/_build/prod/rel/teslamate/bin/teslamate start
ExecStop=/usr/src/teslamate/elixir/_build/prod/rel/teslamate/bin/teslamate stop

[Install]
WantedBy=multi-user.target
```

- `MQTT_HOST` should be the IP address of your MQTT broker. If you do not have one installed, the MQTT functionality can be disabled with `DISABLE_MQTT=true`.
- `TZ` should be your local timezone. Work out your timezone name using the [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) in the linked Wikipedia page.

Start the service:

```bash
sudo systemctl start teslamate
```

And automatically get it to start on boot:

```bash
sudo systemctl enable teslamate
```

</TabItem>
<TabItem value="screen">

Create the following file: `/usr/local/bin/teslamate-start.sh`

You should at least substitute the following details:

- `MQTT_HOST` should be the IP address of your MQTT broker. If you do not have one installed, the MQTT functionality can be disabled with 'DISABLE_MQTT=true'.
- `TZ` should be your local timezone. Work out your timezone name using the [TZ database name](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) in the linked Wikipedia page.
- `TESLAMATEPATH` should be the path that you ran the `git clone` within.

```bash
export ENCRYPTION_KEY="your_secure_encryption_key_here"
export DATABASE_USER="teslamate"
export DATABASE_PASS="your_secure_password_here"
export DATABASE_HOST="127.0.0.1"
export DATABASE_NAME="teslamate"
export MQTT_HOST="127.0.0.1"
export MQTT_USERNAME="teslamate"
export MQTT_PASSWORD="teslamate"
export MQTT_TLS="false"
export TZ="Europe/Berlin"
export TESLAMATEPATH=/usr/src/teslamate

$TESLAMATEPATH/elixir/_build/prod/rel/teslamate/bin/teslamate start
```

The following command needs to be run once during the installation process in order to create the database schema for the TeslaMate installation:

```bash
export ENCRYPTION_KEY="your_secure_encryption_key_here"
export DATABASE_USER="teslamate"
export DATABASE_PASS="your_secure_password_here"
export DATABASE_HOST="127.0.0.1"
export DATABASE_NAME="teslamate"
_build/prod/rel/teslamate/bin/teslamate eval "TeslaMate.Release.migrate"
```

Add the following to /etc/rc.local, to start a screen session at boot time and run the TeslaMate server within a screen session. This lets you interactively connect to the session if needed.

```bash
# Start TeslaMate
cd /usr/src/teslamate
screen -S teslamate -L -dm bash -c "cd /usr/src/teslamate; ./start.sh; exec sh"
```

</TabItem>
</Tabs>

## Import Grafana Dashboards

1. Visit [localhost:3000](http://localhost:3000) and log in. The default credentials are: `admin:admin`.

2. Create a data source with the name "TeslaMate":

   ```grafana
   Type: PostgreSQL
   Default: YES
   Name: TeslaMate
   Host: localhost
   Database: teslamate
   User: teslamate  Password: your_secure_password_here
   SSL-Mode: disable
   Version: 10
   ```

3. Install `jq`:

   ```bash
   sudo apt install jq
   ```

4. [Manually import](https://grafana.com/docs/reference/export_import/#importing-a-dashboard) the dashboard [files](https://github.com/teslamate-org/teslamate/tree/main/grafana/dashboards) or use the `dashboards.sh` script. First create a "Service Account" called `TeslaMate` under Grafana's Administration > User and access menu. Then create an API token for this service account (in place of `<mytoken>` below) and run the script:

   ```bash
   $ env GRAFANA_API_TOKEN=<mytoken> ./grafana/dashboards.sh restore

   URL:                    http://localhost:3000
   GRAFANA_API_TOKEN:      mytoken
   DASHBOARDS_DIRECTORY:   ./grafana/dashboards
   GRAFANA_ORG_NAMESPACE:  default

   RESTORED locations.json into Grafana folder 'TeslaMate' ...
   RESTORED drive-stats.json into Grafana folder 'TeslaMate' ...
   ...
   ```

   :::tip
   To point to a different Grafana instance use the URL variable:

   ```bash
   env URL=https://mygrafana.example.net GRAFANA_API_TOKEN=<mytoken> ./grafana/dashboards.sh restore
   ```

   :::

   :::tip
   In case you use a Grafana installation that runs on a separate server (for
   example, an already existing Grafana install), set the `URL` variable to
   point to it (the default points to `http://localhost:3000`, use a full URL,
   including protocol, host and port):

   ```bash
   URL=<your-grafana-instance-url> ./grafana/dashboards.sh restore
   ```

   :::

## Usage

1. [Generate an access and refresh token](../tokens.md)
2. Open the web interface [http://your-ip-address:4000](http://localhost:4000)
3. Enter the access and refresh token on the sign-in page
4. The Grafana dashboards are available at [http://your-ip-address:3000](http://localhost:3000). Log in with the default user `admin` (initial password `admin`) and enter a secure password.
5. In the TeslaMate web interface, go to _Settings → URLs_ and set the _Web App_ and _Dashboards_ URLs, so the links between TeslaMate and Grafana work in both directions.

## Update

To update the running TeslaMate configuration to the latest version, follow: [Upgrading to a new version](../../upgrading.mdx)

---

### Installation Unsupported Freebsd (`website/docs/installation/unsupported/freebsd.md`)

---
title: Manual install - FreeBSD (no support)
sidebar_label: Manual - FreeBSD (no support)
---

This document provides the necessary steps for installation of TeslaMate in a FreeBSD jail. The **recommended and most straightforward installation approach is through the use of [Docker](../docker.md)**, however this walkthrough provides the necessary steps for manual installation in a FreeBSD 13.0 environment.
It assumes that pre-requisites are met and only basic instructions are provided and should also work in FreeBSD before 13.0.

## Requirements

Click on the following items to view detailed installation steps.

<details>
  <summary>bash & jq</summary>

```bash
pkg install bash jq
bash
```

For simplicity reasons, follow the rest of the tutorial in bash rather the csh.

</details>

<details>
  <summary>git</summary>

```bash
pkg install git
```

</details>

<details>
  <summary>Erlang (v26+)</summary>

```bash
pkg install erlang
```

</details>

<details>
  <summary>Elixir (v1.19+ on Erlang/OTP 28+)</summary>

```bash
pkg install elixir
```

</details>

<details>
  <summary>Postgres (v16.7+, v17.3+ or v18.0+)</summary>

```bash
pkg install postgresql18-server
pkg install postgresql18-contrib
echo postgres_enable="yes" >> /etc/rc.conf
```

</details>

<details>
  <summary>Initialize the database</summary>

```bash
service postgresql initdb
```

</details>

<details>
  <summary>Grafana (v13.1.1+)</summary>

```bash
pkg install grafana
echo grafana_enable="yes" >> /etc/rc.conf
```

</details>

<details>
  <summary>An MQTT Broker (e.g. Mosquitto)</summary>

```bash
pkg install mosquitto
echo mosquitto_enable="yes" >> /etc/rc.conf
```

</details>

<details>
  <summary>Node.js (v22+)</summary>

```bash
pkg install node22
pkg install npm-node22
```

</details>

## Clone TeslaMate git repository

The following command will clone the source files for the TeslaMate project. This should be run in an appropriate directory within which you would like to install TeslaMate. You should also record this path and provide them to the startup scripts proposed at the end of this guide.

```bash
cd /usr/local/src

git clone https://github.com/teslamate-org/teslamate.git
cd teslamate

git checkout $(git describe --tags `git rev-list --tags --max-count=1`) # Checkout the latest stable version
```

## Create PostgreSQL database

The following commands will create a database called `teslamate` on the PostgreSQL database server, and a user called `teslamate`. When creating the `teslamate` user, you will be prompted to enter a password for the user interactively. This password should be recorded and provided as an environment variable in the startup script at the end of this guide. Use 'su - postgres' if unable to enter psql console from current user.

```console
psql
postgres=# create database teslamate;
postgres=# create user teslamate with encrypted password 'your_secure_password_here';
postgres=# grant all privileges on database teslamate to teslamate;
postgres=# ALTER USER teslamate WITH SUPERUSER;
postgres=# \q
```

_Note: The superuser privileges can be revoked after running the initial database migrations._

## Compile Elixir Project

```bash
cd elixir
mix local.hex --force; mix local.rebar --force

mix deps.get --only prod
npm install --prefix ./assets && npm run deploy --prefix ./assets

export MIX_ENV=prod
mix do phx.digest, release --overwrite
```

## Starting TeslaMate at boot time

### Create FreeBSD service definition _/usr/local/etc/rc.d/teslamate_

```
/* Detailed source-code truncated for AI context efficiency. */
```

### Update _/etc/rc.conf_

```bash
echo teslamate_enable="YES" >> /etc/rc.conf
echo teslamate_db_host="localhost"  >> /etc/rc.conf
echo teslamate_db_port="5432"  >> /etc/rc.conf
echo teslamate_db_pass="<super secret>" >> /etc/rc.conf
echo teslamate_encryption_key="<super secret encryption key>" >> /etc/rc.conf
echo teslamate_disable_mqtt="true" >> /etc/rc.conf
echo teslamate_timezone="<TZ Database>" >> /etc/rc.conf #i.e. Europe/Berlin, America/Los_Angeles
```

### Start service

```bash
chmod +x /usr/local/etc/rc.d/teslamate
service teslamate start
```

## Import Grafana Dashboards

1. Visit [localhost:3000](http://localhost:3000) and log in (don't forget to start the service: service grafana start). The default credentials are: `admin:admin`.

2. Create a data source with the name "TeslaMate":

   ```grafana
   Type: PostgreSQL
   Default: YES
   Name: TeslaMate
   Host: localhost
   Database: teslamate
   User: teslamate  Password: your_secure_password_here
   SSL-Mode: disable
   Version: 10
   ```

3. [Manually import](https://grafana.com/docs/reference/export_import/#importing-a-dashboard) the dashboard [files](https://github.com/teslamate-org/teslamate/tree/main/grafana/dashboards) or use the `dashboards.sh` script. First create a "Service Account" called `TeslaMate` under Grafana's Administration > User and access menu. Then create an API token for this service account (in place of `<mytoken>` below) and run the script:

   ```bash
   $ env GRAFANA_API_TOKEN=<mytoken> ./grafana/dashboards.sh restore

   URL:                    http://localhost:3000
   GRAFANA_API_TOKEN:      mytoken
   DASHBOARDS_DIRECTORY:   ./grafana/dashboards
   GRAFANA_ORG_NAMESPACE:  default

   RESTORED locations.json into Grafana folder 'TeslaMate' ...
   RESTORED drive-stats.json into Grafana folder 'TeslaMate' ...
   ...
   ```

   :::tip
   To point to a different Grafana instance use the URL variable:

   ```bash
   env URL=https://mygrafana.example.net GRAFANA_API_TOKEN=<mytoken> ./grafana/dashboards.sh restore
   ```

   :::

## Usage

1. [Generate an access and refresh token](../tokens.md)
2. Open the web interface [http://your-ip-address:4000](http://localhost:4000)
3. Enter the access and refresh token on the sign-in page
4. The Grafana dashboards are available at [http://your-ip-address:3000](http://localhost:3000). Log in with the default user `admin` (initial password `admin`) and enter a secure password.
5. In the TeslaMate web interface, go to _Settings → URLs_ and set the _Web App_ and _Dashboards_ URLs, so the links between TeslaMate and Grafana work in both directions.

## Update

To update the running TeslaMate configuration to the latest version, follow: [Upgrading to a new version](../../upgrading.mdx)

---

### Installation Unsupported Unraid (`website/docs/installation/unsupported/unraid.md`)

---
title: Unraid install (no support)
sidebar_label: Unraid (no support)
---

This document provides the necessary steps for installation of TeslaMate on Unraid. You can either:

- use [Docker Compose for Unraid](https://docs.ibracorp.io/docker-compose/docker-compose-for-unraid) and follow the [Docker Compose installation guide](installation/docker.md) to set up TeslaMate, which is the recommended method and is supported,
- or install the containers individually using the Unraid Community Apps store, without any support.

## Requirements

- Existing Unraid install on v6 or higher with Docker service enabled
- Community Apps store installed
- appdata share configured
- External internet access, to talk to tesla.com

## Installation

Unlike the Compose installation which sets up the following containers in one go, you can install and configure each container individually from Community Apps.

### Postgres

1. Go to the Apps tab for the Community Apps and search for postgresql17 (current version supported) and click install.
2. Verify that no other applications are running on port `5432`
3. Pick a password of your choosing for the database
4. Set `POSTGRES_USER` to `teslamate`
5. Set `POSTGRES_DB` to `teslamate`
6. Click apply and set the container to autostart.

### Mosquitto

1. Go to the Apps tab for the Community Apps and search for mosquitto (for example cmccambridge repository) and click install.
2. Verify that no other applications are running on port `1883`
3. Default template options are mostly fine.
4. Click apply and set the container to autostart.

### TeslaMate

1. Go to the Apps tab for the Community Apps and search for TeslaMate and click install.
2. Verify that no other applications are running on port `4000`
3. **Choose a secure encryption key** that will be used to encrypt your Tesla API tokens (insert as `ENCRYPTION_KEY`).
4. Set the postgres user to `teslamate` and the postgres password to your password from the postgres setup
5. Set the database `teslamate` to match the previous config
6. Set the MQTT host to the IP address of your Unraid server
7. Create an MQTT user and password (required since the default setup is secure)
8. Click apply and optionally set the container to autostart

### TeslaMate-Grafana

1. Go to the Apps tab for the Community Apps and search for TeslaMate Grafana and click install.
2. Verify that no other applications are running on port `3000` (such as another Grafana instance). If so, specify a different port like 3333
3. Specify the TeslaMate database name, username, and password
4. Set the IP of your Unraid server for the host.
5. Click apply and optionally set the container to autostart

## Usage

1. [Generate an access and refresh token](../tokens.md)
2. Open the web interface [http://your-ip-address:4000](http://localhost:4000) or click on the TeslaMate icon and select WebUI.
3. Enter the access and refresh token on the sign-in page
4. The Grafana dashboards are available at [http://your-ip-address:3000](http://localhost:3000). Log in with the default user `admin` (initial password `admin`) and enter a secure password.
5. In the TeslaMate web interface, go to _Settings → URLs_ and set the _Web App_ and _Dashboards_ URLs, so the links between TeslaMate and Grafana work in both directions.

## Update

Check out the [release notes](https://github.com/teslamate-org/teslamate/releases) before upgrading!
To update the running TeslaMate configuration to the latest version, go back to the Apps tab and wait for the Action Center to notify of new updates. Under no circumstances use the Auto Update Applications plugin, as it can easily break your setup, and you won't get any support.

## Unraid Backup and Restore when choosing the individual installation method

### User Scripts Plugin

Go to the Apps tab and search for the User Scripts plugin and install. The plugin can then be accessed from the Settings menu.

### Backup

In the User Scripts plugin, click the Add New Script button. Give the script a name such as `TeslaMate Backup`

Click the gear icon next to the name and Edit Script.

Copy and paste in the following script:

```bash
#!/bin/bash

# Check if array is started
ls /mnt/disk[1-9]* 1>/dev/null 2>/dev/null
if [ $? -ne 0 ]
then
   echo "ERROR:  Array must be started before using this script"
   exit
fi


BACKUP_DIR="/mnt/user/backups/SQL/postgres17"

databases=`docker exec postgresql17 psql -U teslamate teslamate -l -t | cut -d'|' -f1 | sed -e 's/ //g' -e '/^$/d'`

for db in $databases; do  if [ "$db" != "postgres" ] && [ "$db" != "template0" ] && [ "$db" != "template1" ] && [ "$db" != "template_postgis" ]; then
    FOLDER=$BACKUP_DIR/$db

    echo "Backing up $db"
    mkdir -p "$FOLDER"

    FILENAME=${db}_$(date +%A).sql
    FILEPATH=$FOLDER/$FILENAME
    docker exec postgresql17 pg_dump --clean -h 127.0.0.1 -U teslamate -d $db > $FILEPATH
    tar czf $FILEPATH.tgz -C $FOLDER $FILENAME
    rm $FILEPATH
    fi
done

find $BACKUP_DIR/ -type f -name '*.tgz' -mtime +7 -exec rm {} \;
```

:::note
Change the `BACKUP_DIR` path to a share on your server where you want to save backups. Make sure you have the mover settings configured correctly on your share or also have some other backup process for these files since they are still on your server.
:::

:::note
If you changed `DB_USER` in the template from one of the advanced guides, make sure to replace the first instance of `teslamate` and again after the -U in in the above command.
:::

Click **RUN SCRIPT** to test and verify that it works. If you are satisfied, you can select Scheduled Daily from the drop-down to run the cron job every day and create a backup file every day with the day of the week in the file name. Make sure to the click **Run in Background**

### Restore

1. Manually stop all TeslaMate docker containers (TeslaMate-Grafana, TeslaMate).
2. In the User Scripts plugin, click the Add New Script button. Give the script a name such as `TeslaMate Restore`
3. Click the gear icon next to the name and Edit Script.
4. Copy and paste the following script and then Click **RUN SCRIPT**

```
/* Detailed source-code truncated for AI context efficiency. */
```

:::note
Replace the `BACKUP_DIR` value with the value defined in the previous backup file.
:::

:::note
Replace the `DB_CONTAINER` value with the name of the container you want the restore to go **to**.
:::

:::note
Replace the default `teslamate` value below with the value defined in the template if you have one (DB_USER and DB_NAME)
:::

### Postgres Upgrade

1. Run the Backup script
2. Go to the Apps tab and search for the latest recommended postgres version and install a new container instance. Then shut it down.
3. Edit the Restore script `DB_CONTAINER` with the name of the new postgres container you just installed and specify the `BACKUP_DIR`
4. Click RUN SCRIPT
5. Select the backup file you want to restore.
6. Start the new postgres, TeslaMate, and TeslaMate-Grafana containers and verify that your data is correct.
7. When you are certain everything is working as expected, you can delete the old postgres container and image (optional)

---

--- METRICS ---
- Files Extracted: 28
- Estimated Token Budget: ~49041 tokens
- Canonical Reference: https://codewiki.google/github.com/teslamate-org/teslamate
