teslamate Documentation

A self-hosted data logger for your Tesla 🚘 [main maintainer=@JakobLichterfeld]

RAW Doc

Docker & Self-Hosted Deployment Verified OCI

Deploy teslamate on any server, homelab, or cloud container platform.

1-Click Terminal Command
bash (docker run)
docker run -d --name teslamate -p 3000:3000 --restart always teslamate-org/teslamate:latest

Technical Documentation: teslamate-org/teslamate

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

Overview (`README.md`)

TeslaMate








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

  • Written in Elixir
  • Data is stored in a Postgres database
  • Visualization and data analysis with Grafana
  • Vehicle data is published to a local 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:

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

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.

Screenshots

Sneak peak into TeslaMate interface and bundled dashboards. See the docs 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 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 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.

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). 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 to legally defend the project against license violations.

Popularity

Credits

  • Initial Author: Adrian Kumpf
  • List of Contributors:

Overview (`website/README.md`)

Website

This website is built using Docusaurus 2, a modern static website generator and automatically deployed to 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. 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. 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 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 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 (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.

While Grafana 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 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

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.

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.

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 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.

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) 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

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 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 would reset the car's inactivity timer, preventing the car from falling asleep.

Calling the Vehicle API 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. This is what the Home Assistant integration 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. 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; 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 based on contents of TeslaMate MQTT's topic.

LINK: 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, Tibber, aWATTar or fixed pricing (manually specified).

LINK: 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

[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

[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

[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

LINK: Wiki How-To

[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

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

Collection of custom dashboards for Grafana.

LINK: 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

[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

[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 project to retrieve the data and display it in a beautiful and clean way.

LINK: https://github.com/vide/matedroid

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

A Magic Mirror Module for TeslaMate.

LINK: 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 endpoint and a streaming server based on Tesla Telemetry events.

LINK: MyTeslaMate Website

LINK: Follow this guide 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

[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

[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


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

Battery Health

Charge Level

Charges

Charge Details

Charging Stats

Database Information

Drive Stats

Drives

Drive Details

Efficiency

Location (addresses)

Mileage

Overview

Projected Range

States

Statistics

Temperatures

Timeline

Trip

Updates

Vampire Drain

Visited (Lifetime driving map)


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


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

:::warning
Create a backup before updating!
:::

:::info
Check the Release Notes 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
:::

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', },
]}>

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

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.

  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
  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

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 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

text
/* 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

[email protected]

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.

text
/* 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 installed (e.g. with htaccesstools). 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
  2. Sign in with your Tesla account
  3. The Grafana dashboards are available at 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 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.

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

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

If you are upgrading from the simple Docker setup make sure that you are using the same Postgres version as before. To upgrade to a new version see Upgrading PostgreSQL.

.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

[email protected]

If you are upgrading from the simple Docker setup 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 installed (e.g. with htaccesstools). 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, 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 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 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
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 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: the Owner API is being shut down. 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 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 will also be applied soon to the API Owner.

Tesla Fleet Telemetry: non compatible by default

The Tesla 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) is complex.
You can use a 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 website with your Tesla account and go to the MyTeslaMate Fleet page to get your TOKEN.
  2. 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.

  1. You need to "Pair your vehicle(s)" on the fleet page

  2. 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
  3. Restart your instance

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

Teslemetry Fleet API

Important: Teslemetry's vehicle data polling is pay-per-use.

  1. Log in the Teslemetry website and create your TOKEN.

  2. 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
  3. 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

Tesla Fleet API

  1. Set up a third-party account at developer.tesla.com as described on the Tesla docs

  2. Add the following environment variable with your own domain :

    1. Use the correct region in the TESLA_API_HOST field:
    2. 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
  3. (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
    2. Send test commands or setup Telemetry to stream it to your TeslaMate

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
  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 instance on a public domain (eg: telemetry.mydomain.com)

  2. Add a Google pubsub dispatcher to your own GCP PubSub.

  3. Setup a MyTeslaMate Streaming Server from Fleet Telemetry Events on a public domain (eg: streaming.mydomain.com)

  4. Manually create a subscription to the telemetry_V created in PubSub by the Tesla Telemetry with:

  5. Update your environment variables:

    yml
    - TESLA_WSS_HOST=wss://streaming.mydomain.com
    - TESLA_WSS_TLS_ACCEPT_INVALID_CERTS=true
    - TESLA_WSS_USE_VIN=true
  6. 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. 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.
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 (or for chinese: 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
TESLA_AUTH_PATH The Tesla authentication path /oauth2/v3
TESLA_AUTH_CLIENT_ID Client ID of the application registered on 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.

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 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 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 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 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.
    • 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 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 OF YOUR DATA‼️

  • If you have been using TeslaMate since before the 1.16 release, the docker-compose.yml 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.

    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

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

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.
    :::

  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.

:::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 for an example how to use Traefik with TeslaMate. Or you can use the advanced guides with Apache to set up TeslaMate with Apache2, TLS and HTTP Basic Auth.
:::

Requirements

  • Docker (if you are new to Docker, see Installing Docker and Docker Compose)
  • 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:

    text

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

text
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
  2. Open the web interface http://your-ip-address: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. 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


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.

:::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) for secured access to your TeslaMate instance outside your home network.
Alternatively, you can use a reverse proxy (such as Traefik or 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)
  • 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.

The options for the module are documented in the 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
  2. Open the web interface http://your-ip-address: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. 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


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.

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 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 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 client installed or use Telegram's browser interface
  • your own Telegram Bot, see Creating a new telegram bot
  • your own Telegram chat id, see Get your Telegram chat ID

Installing Node-RED

Visit the Node-RED 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
  • 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';

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 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):

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_ids 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//... 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 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.

text
/* 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.

text
/* 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

text
/* 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 { "latitude": 35.278131, "longitude": 29.744801} 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
:::

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', },
]}>

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.
:::

You can use the idiomatic backup script:

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

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
:::

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', },
]}>

  • 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.
  • 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.

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', },
]}>

bash
docker compose exec teslamate bin/teslamate rpc \
    "TeslaMate.Repo.get!(TeslaMate.Log.Drive, 9999) |> TeslaMate.Log.close_drive()"
bash
docker compose exec teslamate bin/teslamate rpc \
    "TeslaMate.Repo.get!(TeslaMate.Log.ChargingProcess, 9999) |> TeslaMate.Log.complete_charging_process()"
bash
teslamate-close-drive 9999
bash
teslamate-close-charge 9999

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', },
]}>

  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:

    text
    ```sql
            DELETE FROM drives WHERE id = 9999;
            ```
  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;

You can use the idiomatic maintenance script:

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

You can use the idiomatic maintenance script:

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

Remove a vehicle from the database

NOTE: Always backup 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;
  1. 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
:::

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', },
]}>

:::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

You can use the idiomatic restore script, for example:

bash
teslamate-restore teslamate_20250805-1622.bck

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

  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 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 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, 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.

Postgres (v16.7+, v17.3+ or v18.0+)

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

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

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

Elixir (v1.19+ on Erlang/OTP 28+)

The Erlang and Elixir packages of Debian stable are too old, so install both with mise. 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 [email protected]

Run the compile steps as the same user, so mix is on the PATH.

Source: mise.jdx.dev/lang/elixir

Grafana (v13.2.3+)

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

Import the Grafana dashboards after cloning the TeslaMate git repository.

An MQTT Broker (e.g. Mosquitto)

bash
sudo apt-get install -y mosquitto

Source: mosquitto.org/download

Node.js (v22+)

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

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

bash
sudo apt install nodejs npm

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', },
]}>

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 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

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 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"

Import Grafana Dashboards

  1. Visit 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 the dashboard files 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
  2. Open the web interface http://your-ip-address: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. 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


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, 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.

bash & jq

bash
pkg install bash jq
bash

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

git

bash
pkg install git

Erlang (v26+)

bash
pkg install erlang

Elixir (v1.19+ on Erlang/OTP 28+)

bash
pkg install elixir

Postgres (v16.7+, v17.3+ or v18.0+)

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

Initialize the database

bash
service postgresql initdb

Grafana (v13.1.1+)

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

An MQTT Broker (e.g. Mosquitto)

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

Node.js (v22+)

bash
pkg install node22
pkg install npm-node22

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_

text
/* 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 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 the dashboard files 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
  2. Open the web interface http://your-ip-address: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. 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


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:

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
  2. Open the web interface http://your-ip-address: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. 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 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
text
/* 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 ---