Energie & Haushalt · Anleitung · Stand September 2026
TeslaMate auf dem Raspberry Pi einrichten.
Schritt für Schritt zur kostenlosen, selbst gehosteten Tesla-Datenerfassung: Fahrten, Ladungen, Akkuzustand und Verbrauch landen in deiner eigenen Datenbank. Kein Abo und keine Cloud.
Inhalt
- 00Vorab: vier wichtige Fakten
- 01System prüfen
- 02Docker installieren
- 03Ordner & .env mit Geheimnissen
- 04docker-compose.yml
- 05Tokens mit Tesla Auth
- 06Starten & anmelden
- 07MQTT: ioBroker / Home Assistant
- 08Vorhandene Grafana nutzen
- 09Andere Rechner auf die DB
- 10Backup & Wiederherstellung
- 11Aktualisieren
- 12Fernzugriff & Komfort
- 13Fehlerbilder & Lösungen
TeslaMate ist ein Open-Source-Projekt, das dein Auto über die Tesla-API abfragt und alles lokal in PostgreSQL speichert: Fahrten, Ladungen, Akkuzustand, Standorte, Reifendruck. Grafana macht daraus fertige Auswertungen. Im Unterschied zu Tessie oder TeslaFi fallen keine laufenden Kosten an, und die Daten gehören dir.
Diese Anleitung nutzt die inoffizielle Owner API (der TeslaMate-Standard) und hält alles im Heimnetz. Sie baut auf der offiziellen Docker-Anleitung auf und ergänzt, was im Alltag fehlt: Sicherheit, Backup, Updates und die Anbindung an ioBroker oder eine vorhandene Grafana.
Vier Fakten, die dir Ärger ersparen
403 Forbidden und zeichnen still nichts mehr auf. Aktuell ist 4.2.0. 4.1.0 bitte überspringen, es stürzt mit aktivem MQTT in einer Startschleife ab (behoben in 4.1.1).
uname -m muss aarch64 (oder x86_64) liefern, also Raspberry Pi 3 oder neuer mit 64-bit-System.
:nxdomain), dann erreicht TeslaMate die Tesla-Server nicht. Einfach auf eine neuere Version aktualisieren.
System prüfen
- Raspberry Pi 3/4/5 mit 64-bit-Raspberry-Pi-OS bzw. Debian 12 oder neuer, mindestens 1 GB RAM, empfohlen 2 GB
- Ein Tesla-Konto und ein Rechner mit Browser (Windows, Mac oder Linux-Desktop) zum Erzeugen der Tokens
- Empfohlen: SSD statt SD-Karte, denn die Datenbank schreibt beim Fahren alle paar Sekunden
uname -m # muss aarch64 oder x86_64 sein cat /etc/os-release | head -2 df -h / /home # freier Speicher (ein paar GB reichen für Jahre) findmnt -no SOURCE / # /dev/mmcblk… = SD-Karte, /dev/sd… oder /dev/nvme… = SSD sudo ss -tlnp | grep -E ':(4000|3000|1883|5432) ' # sind die Ports schon belegt?
/etc/docker/daemon.json {"data-root": "/mnt/ssd/docker"} eintragen und Docker neu starten, bevor du TeslaMate installierst.
Docker & Docker Compose installieren
Das offizielle Skript richtet Docker samt docker compose-Plugin ein:
curl -fsSL https://get.docker.com | sh sudo usermod -aG docker $USER # danach ab- und wieder anmelden docker --version # bitte nicht 29.1.0 docker compose version
Ist Docker schon installiert und die Version 29.1.0, aktualisierst du so: sudo apt update && sudo apt install --only-upgrade docker-ce docker-ce-cli containerd.io docker-compose-plugin. Docker startet dank systemctl enable docker (macht das Skript) beim Booten automatisch, und restart: always in der Compose-Datei holt die Container mit. Ein eigener systemd-Dienst für TeslaMate ist nicht nötig.
Ordner & .env mit Geheimnissen
Alle Passwörter kommen in eine eigene Datei .env, nicht in die Compose-Datei. Die Zufallswerte erzeugt openssl direkt beim Anlegen:
mkdir -p ~/teslamate && cd ~/teslamate umask 077 cat > .env <<EOF ENCRYPTION_KEY=$(openssl rand -hex 32) DATABASE_PASS=$(openssl rand -hex 24) GRAFANA_ADMIN_PASS=$(openssl rand -hex 16) TZ=Europe/Vienna EOF chmod 600 .env cat .env # Werte einmal ansehen und im Passwortmanager sichern
ENCRYPTION_KEY verschlüsselt die Tesla-Tokens in der Datenbank. Geht er verloren oder wird er geändert, musst du die Tokens neu eintragen. Die Fahrdaten bleiben erhalten. Die .env gehört nie in ein Git-Repository und nie in einen Web-Ordner.
docker-compose.yml anlegen
Die Datei folgt der offiziellen Vorlage (Stand September 2026). Es gibt nur drei Ergänzungen: Die Geheimnisse kommen aus der .env, Grafana bekommt ein Admin-Passwort ohne anonymen Zugriff, und die Zeitzone ist gesetzt. Postgres und Mosquitto bekommen keine Ports nach außen, nur TeslaMate (4000) und Grafana (3000) sind im LAN erreichbar.
services: teslamate: image: teslamate/teslamate:latest restart: always environment: - ENCRYPTION_KEY=${ENCRYPTION_KEY} - DATABASE_USER=teslamate - DATABASE_PASS=${DATABASE_PASS} - DATABASE_NAME=teslamate - DATABASE_HOST=database - MQTT_HOST=mosquitto - TZ=${TZ} ports: - 4000:4000 volumes: - ./import:/opt/app/import cap_drop: - all database: image: postgres:18-trixie restart: always environment: - POSTGRES_USER=teslamate - POSTGRES_PASSWORD=${DATABASE_PASS} - POSTGRES_DB=teslamate volumes: - teslamate-db:/var/lib/postgresql # ab PG 18 ohne /data grafana: image: teslamate/grafana:latest restart: always environment: - DATABASE_USER=teslamate - DATABASE_PASS=${DATABASE_PASS} - DATABASE_NAME=teslamate - DATABASE_HOST=database - GF_SECURITY_ADMIN_USER=admin - GF_SECURITY_ADMIN_PASSWORD=${GRAFANA_ADMIN_PASS} - GF_AUTH_ANONYMOUS_ENABLED=false ports: - 3000:3000 # 3000 schon belegt? z. B. 3001:3000 oder Schritt 8 volumes: - teslamate-grafana-data:/var/lib/grafana mosquitto: image: eclipse-mosquitto:2 restart: always command: mosquitto -c /mosquitto-no-auth.conf # bewusst ohne ports: nur für Container im selben Compose-Netz erreichbar volumes: - mosquitto-conf:/mosquitto/config - mosquitto-data:/mosquitto/data volumes: teslamate-db: teslamate-grafana-data: mosquitto-conf: mosquitto-data:
TESLA_API_HOST, TESLA_AUTH_* und TESLA_WSS_* nicht setzen. Sie sind nur für die offizielle Fleet API gedacht (eigene Tesla-Entwickler-App, siehe Doku).
INFLUXDB_HOST werden ignoriert. Wer Werte in InfluxDB haben will, holt sie über MQTT (z. B. ioBroker oder Telegraf, Schritt 7).
Access- & Refresh-Token mit Tesla Auth
TeslaMate braucht einen Access Token und einen Refresh Token. Am sichersten erzeugst du sie mit Tesla Auth, der kleinen Open-Source-App, die auch die TeslaMate-Doku empfiehlt. Sie öffnet das originale Login-Fenster von Tesla auf deinem eigenen Rechner (inkl. MFA und Captcha). Dein Passwort geht an niemanden außer Tesla.
Direkt-Downloads der aktuellen Version: Windows · macOS Apple Silicon · macOS Intel · Linux x86_64 · Linux ARM
So geht's
- Passende Datei herunterladen und entpacken. Die Prüfsummen stehen als
.sha256auf der Release-Seite. tesla_authstarten (Doppelklick oder im Terminal). Windows fragt eventuell nach, weil die App nicht signiert ist. Unter Linux braucht sielibwebkit2gtk-4.1undlibxdo.- Im Tesla-Fenster mit E-Mail, Passwort und MFA-Code anmelden.
- Das letzte Fenster zeigt beide Tokens. Kopieren, aber nirgends speichern oder verschicken, gleich in Schritt 6 eintragen.
Starten, anmelden, einstellen
cd ~/teslamate docker compose up -d docker compose ps docker compose logs -f teslamate # Strg+C beendet nur die Anzeige
Im Log sollten die Datenbank-Migrationen durchlaufen und Running TeslaMateWeb.Endpoint … at :::4000 erscheinen. Dann im Browser öffnen:
http://<IP-des-Pi>:4000 # TeslaMate http://<IP-des-Pi>:3000 # Grafana, Login admin + GRAFANA_ADMIN_PASS aus der .env
- Unter
:4000die beiden Tokens aus Schritt 5 eintragen und Sign in klicken. - Im Log steht dann
POST https://auth.tesla.com/oauth2/v3/token -> 200undScheduling token refresh. - Unter Settings Sprache wählen und die Einheiten auf km und °C stellen.
- Unter Geofences dein Zuhause anlegen und dort den Strompreis pro kWh hinterlegen, dann rechnet TeslaMate die Ladekosten mit.
MQTT: vorhandenen Broker nutzen (ioBroker, Home Assistant)
TeslaMate veröffentlicht alle Live-Werte unter teslamate/cars/1/… (Akkustand, Standort, Ladeleistung, Zustand …). Damit lassen sich Wallbox, PV-Überschussladen oder Anzeigen in ioBroker bzw. Home Assistant steuern.
Läuft im Netz schon ein Broker (etwa der ioBroker-Adapter MQTT Broker/Client im Server-Modus), dann den mosquitto-Dienst aus der Compose-Datei streichen und TeslaMate direkt dorthin zeigen lassen:
environment: # … wie oben, aber statt MQTT_HOST=mosquitto: - MQTT_HOST=host.docker.internal # Broker auf demselben Rechner, sonst dessen IP - MQTT_PORT=1883 - MQTT_USERNAME=${MQTT_USERNAME} - MQTT_PASSWORD=${MQTT_PASSWORD} extra_hosts: - "host.docker.internal:host-gateway"
MQTT_USERNAME und MQTT_PASSWORD in die .env eintragen und denselben Benutzer im Broker anlegen. Im Log muss danach MQTT connection has been established stehen. Brauchst du MQTT gar nicht, setzt du DISABLE_MQTT=true und lässt Mosquitto weg.
iob set mqtt.0 --pass … zeigt es auf der Konsole an und speichert es unverschlüsselt. Außerdem schreibt der Adapter bei falschen Anmeldungen das gesendete Passwort ins Log. Nach Tippfehlern beim Einrichten das Passwort daher neu setzen.
Vorhandene Grafana statt Container
Läuft auf dem Pi schon eine Grafana (Port 3000), kannst du deren Dashboards weiter nutzen und den grafana-Dienst aus der Compose-Datei streichen. Dann braucht die Grafana Zugriff auf Postgres, aber nur über localhost:
ports: - 127.0.0.1:5432:5432 # nie "5432:5432" – das wäre fürs ganze LAN offen
Datasource anlegen
apiVersion: 1 datasources: - name: TeslaMate uid: TeslaMate # so erwarten es die Dashboards, kein UID-Ersetzen nötig type: postgres access: proxy url: localhost:5432 user: teslamate secureJsonData: password: "DATABASE_PASS aus der .env" jsonData: database: teslamate # Pflicht ab Grafana 10 sslmode: disable editable: false
sudo chown root:grafana /etc/grafana/provisioning/datasources/teslamate.yaml sudo chmod 640 /etc/grafana/provisioning/datasources/teslamate.yaml
Dashboards passend zur TeslaMate-Version
Die Dashboards gehören zur jeweiligen TeslaMate-Version und kommen mit dem Release-Archiv. V immer auf die installierte Version setzen:
V=4.2.0 D=/etc/grafana/provisioning/dashboards/teslamate sudo mkdir -p $D curl -sL https://github.com/teslamate-org/teslamate/archive/refs/tags/v$V.tar.gz \ | sudo tar -xz --strip-components=3 -C $D teslamate-$V/grafana/dashboards sudo rm -rf $D/reports # enthält nur einen niederländischen Steuerreport sudo chown -R root:grafana $D
apiVersion: 1 providers: - name: TeslaMate orgId: 1 folder: TeslaMate type: file options: path: /etc/grafana/provisioning/dashboards/teslamate foldersFromFilesStructure: false - name: TeslaMate Internal # Fahrt- und Ladedetails, auf die die Dashboards verlinken orgId: 1 folder: TeslaMate Internal type: file options: path: /etc/grafana/provisioning/dashboards/teslamate/internal
sudo systemctl restart grafana-serversudo sed -i 's/"uid": "TeslaMate"/"uid": "DEINE_UID"/g' $D/*.json $D/internal/*.json.
/etc/grafana/grafana.ini unter [auth.anonymous] muss enabled = false stehen. Vorher prüfen, ob irgendeine Webseite Grafana-Panels eingebettet hat, die brauchen sonst einen Login.
Anderen Rechnern Lesezugriff auf die Datenbank geben
Sollen eigene Dashboards, eine Wallbox-Steuerung oder Auswertungen auf einem anderen Rechner die TeslaMate-Daten lesen, dann nicht den TeslaMate-Benutzer weitergeben und nicht das ganze LAN öffnen. Zwei Bausteine reichen. In den Beispielen ist 192.168.1.10 der TeslaMate-Pi und 192.168.1.20 der Rechner, der lesen darf.
1. Eigener Benutzer mit reinen Leserechten
cd ~/teslamate
echo "RO_PASS=$(openssl rand -hex 24)" >> .env
docker compose exec -T database psql -U teslamate -d teslamate \
-v pw="$(grep ^RO_PASS= .env | cut -d= -f2)" <<'SQL'
SELECT format('CREATE ROLE auswertung_ro LOGIN PASSWORD %L', :'pw') \gexec
ALTER ROLE auswertung_ro SET default_transaction_read_only = on;
GRANT CONNECT ON DATABASE teslamate TO auswertung_ro;
GRANT USAGE ON SCHEMA public TO auswertung_ro;
GRANT SELECT ON ALL TABLES IN SCHEMA public TO auswertung_ro;
ALTER DEFAULT PRIVILEGES FOR ROLE teslamate IN SCHEMA public
GRANT SELECT ON TABLES TO auswertung_ro;
SQLDer Benutzer sieht alle Fahrten, Ladungen und Positionen, auch Tabellen aus künftigen Updates. Auf das Schema private mit den Tokens hat er keinen Zugriff, und schreiben kann er nicht.
2. Port nur für diesen einen Rechner
ports: - 127.0.0.1:5432:5432 # Grafana auf dem Pi (falls genutzt) - 192.168.1.10:5432:5432 # LAN – per Firewall eingeschränkt
Docker umgeht normale Firewall-Regeln wie ufw. Die Regel gehört deshalb in die Kette DOCKER-USER:
sudo iptables -I DOCKER-USER -p tcp -m conntrack \
--ctorigdst 192.168.1.10 --ctorigdstport 5432 --ctdir ORIGINAL \
! -s 192.168.1.20 -j DROPAfter=docker.service, PartOf=docker.service und WantedBy=docker.service ausführen lassen. Im Skript vorher mit iptables -C prüfen, ob die Regel schon existiert. Kontrolle: sudo iptables -S DOCKER-USER.
Tägliches Backup & Wiederherstellung
Das Skript sichert die Datenbank komprimiert mit Datum im Dateinamen, prüft, ob der Dump vollständig ist, und behält 14 Tage:
#!/bin/bash
set -o pipefail; umask 077
DIR="$(cd "$(dirname "$0")" && pwd)"; DEST="$DIR/backups"; KEEP_DAYS=14
FILE="$DEST/teslamate_$(date +%F_%H%M).sql.gz"
mkdir -p "$DEST" && cd "$DIR" || exit 1
if docker compose exec -T database pg_dump -U teslamate teslamate | gzip > "$FILE.tmp" \
&& gunzip -c "$FILE.tmp" | tail -n 5 | grep -q 'PostgreSQL database dump complete'; then
mv "$FILE.tmp" "$FILE"; echo "$(date '+%F %T') OK $(basename "$FILE")" >> "$DEST/backup.log"
else
rm -f "$FILE.tmp"; echo "$(date '+%F %T') FEHLER" >> "$DEST/backup.log"; exit 1
fi
find "$DEST" -maxdepth 1 -name 'teslamate_*.sql.gz' -mtime +$((KEEP_DAYS-1)) -deletechmod 700 ~/teslamate/backup.sh && ~/teslamate/backup.sh && ls -lh ~/teslamate/backups (crontab -l 2>/dev/null; echo "15 3 * * * $HOME/teslamate/backup.sh") | crontab -
Wiederherstellen
Nach der offiziellen Anleitung. Der ENCRYPTION_KEY in der .env muss derselbe wie beim Backup sein:
cd ~/teslamate
docker compose stop teslamate
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;
.
gunzip -c backups/teslamate_JJJJ-MM-TT_HHMM.sql.gz \
| docker compose exec -T database psql -U teslamate -d teslamate
docker compose start teslamateAktualisieren
Vorher kurz die Release-Notes lesen, dann:
cd ~/teslamate ./backup.sh # immer zuerst! docker compose pull docker compose up -d docker compose logs -f teslamate # Migrationen abwarten, auf Fehler achten
Nutzt du eine vorhandene Grafana (Schritt 8), die Dashboards danach mit der neuen Versionsnummer erneut herunterladen.
Sonderfall: neue PostgreSQL-Hauptversion
Wechselt die Doku auf eine neue Hauptversion (z. B. von postgres:16 auf postgres:18-trixie), reicht es nicht, den Tag zu ändern: Die neue Version kann die alten Datenbankdateien nicht lesen. Der sichere Weg führt über ein neues Volume. Das alte bleibt als Rückfallebene liegen:
./backup.shausführen, danndocker compose down.- In der Compose-Datei Image und Volume-Name ändern, z. B.
teslamate-db18:/var/lib/postgresql(auch unten untervolumes:). docker compose up -d databaseund warten, bis im LogPostgreSQL init process completesteht. Postgres startet beim ersten Mal zweimal, und ein zu früher Restore läuft ins Leere.- Backup einspielen:
gunzip -c backups/….sql.gz | docker compose exec -T database psql -U teslamate -d teslamate docker compose up -d. TeslaMate meldet im LogPostgreSQL version 18.x is compatible.- Nach ein paar ruhigen Wochen das alte Volume mit
docker volume rm teslamate_teslamate-dblöschen.
Details: Upgrading PostgreSQL.
Fernzugriff & schöne Adressen
Von unterwegs: nur per VPN
Mit Tailscale oder WireGuard (viele Router und Firewalls können das selbst) bist du von unterwegs im Heimnetz und öffnest http://<IP-des-Pi>:4000 wie zu Hause. Es braucht keine Portfreigabe, und fremde Scanner finden nichts.
Namen statt IP-Adressen
Mit einem lokalen DNS wie AdGuard Home oder Pi-hole unter DNS-Umschreibungen bzw. Local DNS eintragen:
teslamate.heimnetz.local → <IP-des-Pi> grafana.heimnetz.local → <IP-des-Pi>
Ohne Reverse-Proxy bleibt der Port Teil der Adresse (:4000, :3000). Soll der VPN-Zugang die Namen auch kennen, muss dieser DNS-Server im VPN verteilt werden (bei Tailscale z. B. per Split-DNS).
step-ca) liefert https://teslamate.heimnetz.local ohne Port. Den Proxy nur an die LAN-Adresse binden, nicht an einen Tunnel.
Fehlerbilder & Lösungen
Seit Wochen keine neuen Daten, im Log 403 oder not_signed_in
- TeslaMate älter als 4.0.1: Die Token-Erneuerung scheitert. Aktualisieren (Schritt 11), danach neue Tokens mit Tesla Auth eintragen.
fuse_blownim Log heißt: TeslaMate pausiert nach wiederholten API-Fehlern. Das löst sich nach erfolgreicher Anmeldung von selbst (alarm_handler … clear).
:nxdomain beim Verbinden zu Tesla
docker --versionprüfen. Bei 29.1.0 Docker aktualisieren (Schritt 2).
TeslaMate startet nach Update immer wieder neu
- Version 4.1.0 mit MQTT und ohne
MQTT_NAMESPACE: auf 4.1.1 oder neuer gehen.
Auto zeigt dauerhaft „asleep"
- Normal. TeslaMate weckt das Auto nie. Die Tesla-App öffnen oder losfahren, dann geht es binnen etwa einer Minute auf
online. - Kilometerstand und Akkustand zeigen bis dahin die letzten bekannten Werte.
Grafana zeigt überall „No data"
database: teslamatefehlt unterjsonDatader Datasource (Pflicht ab Grafana 10), oder die Datasource-UID passt nicht zu den Dashboards (Schritt 8).- Danach
sudo systemctl restart grafana-serverund die Seite mit Strg+Shift+R neu laden.
Ein anderes Programm kommt plötzlich nicht mehr an die Datenbank
- Meldung
connection to server at "…", port 5432 failed: Connection refused: Postgres ist nur noch an localhost gebunden. Mit Leserechten und Firewall freigeben, siehe Schritt 9.
Nützliche Links
Fertig! TeslaMate läuft.
Ab jetzt landet jede Fahrt und jede Ladung in deiner eigenen Datenbank. Das tägliche Backup läuft, das nächste Update ist ein Dreizeiler, und aus dem Internet ist nichts davon erreichbar.
← Zurück zur Startseite