e홈서버에 테슬라메이트를 설치하고자 한다. 테슬라메이트는 테슬라의 주행기록 프로그램으로 이와 관련 앱으로 tessie라고 유용한게 있다. 스마트폰으로 간편하게 설정하고, 히스토리를 확인할 수 있지만 구독제이고, 무엇보다 디자인이 썩 마음에 들지 않았다. 테슬라메이트는 무료설치가 가능한 대신 설치와 설정이 다소 어렵다. 무엇보다 서버가 필요한데, 나는 홈서버(Proxmox)를 돌리고 있기 때문에 여기에 설치를 시도해 보고자 한다.
1. 설치하기
Docker install | TeslaMate
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. For a walkthrough that provides the necessary steps for manual installation see Manual installati
docs.teslamate.org
테슬라메이트 공식 문서이다. 설치법은 간단하고 나는 Docker installation을 하고자 한다. Proxmox에 docker을 설치 하였고, 함께 portainer을 설치하여 관리하고 있다. (docker-portainer 설치도 NPM과 마찬가지로 https://community-scripts.github.io/ProxmoxVE/scripts?id=docker 에서 간편하게 설치하였다.)
Portainer를 통하여 테슬라메이트 설치하는 방법은 간단하다. 우선 파일을 준비해야 한다. 공식문서에도 나와있듯 메모장과 같은 프로그램을 이용하여 docker-compose.yml 파일을 작성한다.
그냥 위에 첨부한 파일을 써도 되고, 여기서 아래에 secretkey, password 부분을 자신에게 맞게 설정을 하자.
ENCRYPTION_KEY=secretkey #replace with a secure key to encrypt your Tesla API tokens
DATABASE_PASS=password #insert your secure database password!
POSTGRES_PASSWORD=password #insert your secure database password!
DATABASE_PASS=password #insert your secure database password!
secretkey는 그냥 아무거나 적어도 상관없다. ID도 아니고 password도 아니다. 암호화키? 정도로만 알고 있으면 되는데, 나중에 password처럼 요청하는것도 아니니 그냥 적당히 아무값이나 넣어주자. (ABCDEFG1234 이런식도 상관없다. 테슬라에서 정보를 받아올때 필요한것 같다.) 대신 password는 모두 똑같이 작성하도록 하자. 이게 password가 다르면 에러가 발생해서 실행이 되지 않는다.
파일을 준비한 다음에는 Portainer에 들어가서 → local → Stacks → +Add stack (우측위) → upload file → docker-compose.yml 업로드 → Deploy the stack 을 하게되면 설치가 완료된다.

설치후 접속은 http://teslamate_설치ip:4000 으로 테슬라메이트 접속, http://teslamate_설치ip:3000 으로 Grafana 접속을 할 수 있다.
이때 테슬라메이트는 내 테슬라의 주행정보를 받아오는 서버정도로 생각하면 되고, Grafana는 이 정보들을 바탕으로 웹인터페이스의 대시보드를 보여주는 서버로 생각하면 된다.
접속 아이디와 password는 admin / 초기설정한 password로 접속이 가능하다. (Grafana 초기 id / pw 은 admin / admin 이다)
여기서 바로 이용할 수는 없고 테슬라 API key (token) 를 받아와야 한다. token를 받아오는 방법은 여러가지가 있지만, 나는 Auth app for tesla 를 통하여 token을 받아왔다.
Auth app for Tesla
Need to generate modern secure Tesla API authentication tokens? Look no further! Based on the proven implementation of Watch app for Tesla, now you can continue to keep all your custom shortcuts alive, by swapping out your previous token mechanism for t
apps.apple.com

Refresh token 과 Access token 두개 모두 필요하고, 둘다 입력후 이제 대시보드 접속을 하면 웹인터페이스로 접속을 할 수 있다. 이때 Grafana로 연결되게 된다. 기능이 워낙 많아서 다 보여주기는 어렵고, 대표적인 Overview 대시보드는 이렇게 생겼다.

2. Grafana 커스텀 대시보드 꾸미기
테슬라메이트 대시보드가 참 보기가 어렵게 되어 있다. 볼수있는 정보는 많은데, 너무 복잡하다. 테슬라메이트로 주행관련 정보를 모두 저장하고, 이를 Grafana를 통해서 추출하여 통계표처럼 보여주는데, 그렇기 때문에 이 대시보드를 커스터마이징이 가능하다! 이게 JSON으로 뭔가 꾸미는것 같기는 한데….. 비전문가라 사실 잘 모르겠다.
데이터소스는 PostgreSQL을 사용하는것으로 보이고, 대시보드는 JSON을 이용하여 나타내는것 같은데, 웹인터페이스로도 바꿀수 있어 sql만 안다면 어느정도 원하는대로 커스터마이징이 가능해 보인다. sql에 대해서는 어느정도 알고 있기 때문에, 우선 데이터를 확인해 보면서 커스터마이징을 해보겠다. 데이터는 Explore에서 sql 명령어를 (ex. select * from table_name) 통하여 확인이 가능하다. 수집된 데이터가 어떤 형태로 저장되는지는 구글링을 통해서도 잘 알수가 없어, 수집된 데이터를 토대로 유추해보고자 한다.
맨아래 정리한것은 각 테이블의 변수를 정리한것이다. 여기에 포함된 변수라면 얼마든지 활용하여 대시보드를 꾸밀 수 있다. (나중에 대시보드 업데이트를 위하여 자세하게 나타내고자 하고, 사용하면서 업데이트 예정) 그런데 주차/주행상태와 같은 몇몇 변수는 없는것 같다. Tesla API 가 유료로 정책이 바뀌었다고 하는데 이런것들을 못가져오는게 아닌가 싶다.
아직 어려운 부분이지만 ChatGPT의 도움을 받아서 대시보드를 꾸며보았고, 일차적으로 아래와 같이 꾸밀 수 있었다. 좀더 꾸미는 방법은 더 공부하고 고민해 봐야겠다. (나중에 이쁘게 완성하고 나면 공유하겠다.)

예시로 간단하게 지난 한달간 주행거리, 주행시간, 충전량을 나타내는 판낼을 만드는 법을 소개하겠다.
Dashboard → Edit → Visualization 으로 들어가면 대시보드에 표시할 수 있는 판넬을 제작할 수 있다. 여기서 오른쪽 위에서 Stat을 선택해주고, 왼쪽에서 Code를 선택하면 아래 sql 코드를 작성할 수 있는 창이 뜨게된다.

SELECT
(SELECT SUM(distance) FROM drives WHERE start_date >= NOW() - INTERVAL '30 days') AS "주행 거리",
(SELECT SUM(duration_min) FROM drives WHERE start_date >= NOW() - INTERVAL '30 days') AS "주행시간",
(SELECT SUM(charge_energy_added) FROM charging_processes WHERE start_date >= NOW() - INTERVAL '30 days') AS "충전량"
여기에 코드를 작성해주고 Run query를 누르게 되면 위쪽에 데이터가 표시되게 된다. 위 코드를 해석하자면 drives의 테이블에서 현재부터 30일사이의 데이터 중에서 distance의 값을 모두 더해서 "주행 거리" 로 표시해 달라는 내용이다. 그리고 오른쪽 Stat아래 메뉴에서 이 판넬의 글자크기, 모양, 등을 선택할 수 있고, overrides를 활용하여 각 값에 대해서 단위를 표시한다던지 하는 세부조정을 할 수 있다. (이미 만들어져 있는 대시보드를 참조해도 된다)
Carges 대시보드를 보면 Cost를 입력할 수 있는 부분이 있다. 이것을 클릭해보면 충전비용을 직접 입력할 수 있는 곳으로 연결이 된다. Grafana가 아니라 테슬라메이트 쪽으로 연결이 되는데, Cost를 직접 입력을 할 수 있는데, 그런데 문제가 10000원이 넘어가서 10000 이상을 입력하려고 치면 불가능하다. 이게 소수점두자리 포함 총 6자리의 숫자만 입력이 가능해서인데, 이를 고쳐줘야 한다.
Explore의 code 입력부분에서 다음처럼 입력하면 된다.

ALTER TABLE charging_processes
ALTER COLUMN cost TYPE NUMERIC(10,2);
총 10자리를 입력받을수 있게 변환시킨건데, 이렇게 하고 Run query로 실행을 하고, 잠시 대기하고 있으면 이제 10000 이상도 입력이 잘 되게 된다.
addresses : 주소테이블로 생각됨. 어떠한 곳을 방문했을때, 도로명이나 지번주소가 아닌 이름으로 정의하기 위한 테이블 (ex. 서울시 중구 한강대로 420 → 서울역)
| id | id | display_name | 주소 |
| latitude | 위도 | longitude | 경도 |
| name | 이름 | house_number | 주소 세부 |
| road | 도로명 |
neighbourhood
|
동 |
| city | 도시 |
country
|
국가 (대부분 결측임) |
| postcode | 우편번호 | state | 도 (ex. 경기도) |
| raw | dictionary 형식의 모든값 | inserted_at | yyyy. mm. dd. AM hh:mm:ss |
| updated_at | yyyy. mm. dd. AM hh:mm:ss | osm_id | |
| osm_type | "node, way, relation" |
car_settings : 자동차 세팅에 관한 테이블로 추정됨. 하나의 행만 존재.
| id | suspend_min | ||
|
suspend_after_idle_min
|
req_not_unlocked
|
true/false | |
|
free_supercharging
|
true/false |
use_streaming_api
|
true/false |
|
enabled
|
true/false |
lfp_battery
|
true/false |
cars : 자동차에 관한 테이블로 추정됨. 하나의 행만 존재.
| id | id | eid | |
| model | S / 3 / X / Y | efficiency | |
| inserted_at | yyyy. mm. dd. AM hh:mm:ss | updated_at | yyyy. mm. dd. AM hh:mm:ss |
| vin | VIN number | name | |
| trim_badging | setting_id | ||
| exterior_color | 차량 색상 (ex. PearlWhite) | spoiler_type | 스포일러 |
| wheel_type | 휠 타입 | display_priority | |
| marketing_name | 상품명 (ex. LR AWD) |
charges : 충전중 주기별로 (수초간격) 충전 정보
| id | id | date | yyyy. mm. dd. AM hh:mm:ss |
| battery_heater_on | true/false | battery_level | 배터리 잔량 % |
| charge_energy_add | 실시간 충전량 (kWh) | charger_actual_current | 충전 전류 A |
| charge_phases | charger_pilot_current | ||
| charger_power | charger_voltage | ||
| fast_charger_present | 급속충전여부? (false/true) | conn_charge_cable | (ex. SAE) |
| fast_charger_brand | fast_charger_type | ||
| ideal_battery_range_km | 주행가능거리 (km) | not_enough_power_to_heat | |
| outside_temp | 외부기온 (ºC) | charging_process_id | |
| battery_heater | battery_heater_no_power | ||
| rated_battery_range_km | usable_battery_level |
charging_processes : 충전세션별 정보 (총추가량 / 총사용량으로 효율성 계산 가능)
| id | start_date | yyyy. mm. dd. AM hh:mm:ss | |
| end_date | yyyy. mm. dd. AM hh:mm:ss | charge_energy_add | 총 추가량 (kWh) |
| start_ideal_range_km | 충전전 주행가능예상거리 (km) | end_ideal_range_km | 충전후 주행가능예상거리 (km) |
| start_battery_level | 충전전 배터리 잔량 % | end_battery_level | 충전후 배터리 잔량 % |
| duration_min | 충전시간 (min) | outside_temp_avg | |
| car_id | position_id | ||
| address_id | start_rated_range_km | 충전후 주행가능거리 (km) | |
| end_rated_range_km | 충전전 주행가능거리 (km) | geofence_id | |
| charge_energy_used | 총 사용량 (kWh) | cost | 충전비용 (기본 결측) |
drives : 주행세션별 정보 (address_id는 address 테이블에서의 id)
| id | id | start_date | yyyy. mm. dd. AM hh:mm:ss |
| end_date | yyyy. mm. dd. AM hh:mm:ss | outside_temp_avg | 외부기온 평균 (ºC) |
| speed_max | 주행최고속도 (km/h) | power_max | |
| power_min | start_ideal_range_km | 주행전 주행가능예상거리 (km) | |
| end_ideal_range_km | 주행후 주행가능예상거리 (km) | start_km | |
| end_km | distance | 주행거리 (km) | |
| duration_min | 주행시간 (min) | car_id | |
| inside_temp_avg | start_address_id | 시작지 주소 id | |
| end_address_id | 종료지 주소 id | start_rated_range_km | |
| end_rated_range_km | start_position_id | ||
| end_position_id | start_geofene_id | ||
| end_geofence_id |
geofences : 지오펜스 설정값
| id | id | name | 입력이름 |
| latitude | 위도 | longitude | 경도 |
| radius | inserted_at | ||
| updated_at | cost_per_unit | 충전요금 | |
| session_fee | 충전세션 수수료 | billing_type | 충전요금단위 (/kWh or /min) |
positions : 자동차 위치정보
| id | date | yyyy. mm. dd. AM hh:mm:ss | |
| latitude | 위도 | longitude | 경도 |
| speed | power | ||
| odometer | 총주행거리 | ideal_battery_range_km | |
| battery_level | outside_temp | ||
| elevation | fan_status | ||
| driver_temp_setting | passenger_temp_setting | ||
| is_climate_on | is_rear_defroster_on | ||
| is_front_defroster_on | car_id | ||
| drive_id | inside_temp | ||
| battery_heater | battery_heater_on | ||
| battery_heater_no_power | est_battery_range_km | ||
| rated_battery_range_km | usable_battery_level | ||
| tpms_pressure_fl | tpms_pressure_fr | ||
| tpms_pressure_rl | tpms_pressure_rr |
states : 자동차 온/오프라인 여부
| id | state | offline / online | |
| start_date | yyyy. mm. dd. AM hh:mm:ss | end_date | yyyy. mm. dd. AM hh:mm:ss |
| car_id | car id |
updates : 펌웨어 버전
| id | start_date | yyyy. mm. dd. AM hh:mm:ss, 업데이트 시작시간 | |
| end_date | yyyy. mm. dd. AM hh:mm:ss, 업데이트 종료시간 | version | 펌웨어 버전 |
| car_id |
'IoT, 스마트홈, 홈서버' 카테고리의 다른 글
| [홈서버 만들기 #2] Docker 설치하기 (on Proxmox) (1) | 2025.12.15 |
|---|---|
| [홈서버 만들기 #1] Proxmox 설치하기 (0) | 2025.12.14 |
| Nginx Proxy Manager 설정기 (feat. Proxmox) (0) | 2025.01.23 |
| Home assistant 에서 라즈베리파이 + Proxmox CPU 온도 체크하기 (0) | 2023.10.25 |
| Home assistant + 라즈베리파이 + 키오스크 설정기 (4) - HAOS 기본설정 (0) | 2023.10.12 |