This project PedroKTFC/esphome-tesla-ble lets you use an ESP32 device to manage charging a Tesla vehicle over BLE. It is a fork of the yoziru/esphome-tesla-ble and uses a similar fork of the yoziru/tesla-ble library.
Controls | Sensors-1 | Sensors-2 | Diagnostic |
---|---|---|---|
![]() |
![]() |
![]() |
![]() |
These are implemented as switches, covers, buttons or numbers. Where indicated, these use the current sensor value for the control (but be aware that changing a value/state has a delay before it is reflected in the corresponding sensor - it takes time to send the messages to the vehicle to make the control and then read back the new value - it might look like the control has been rejected as the value reverts to the previous value; be patient!).
There are two categories, those available even when asleep and those only when awake.
These are the diagnostic button actions:
There are five number and two switch actions that allow the dynamic update of the polling parameters (see below). These are disabled by default as I recommend they should be changed through yaml but they are useful for tuning/debugging your setup. Note there is no equivalent to the update_interval
parameter - this can still only be updated through yaml (and so a re-build). The following lists them with the equivalent polling parameter:
There are several key parameters that determine the polling activity as follows:
Name | Type | Default | Supported options | Description |
---|---|---|---|---|
update_interval |
number | 10s | any interval | This is the base polling rate in seconds. No other polls can happen faster than this even if you configure them shorter. The base polling checks the overall status using the car’s VCSEC system (Vehicle Controller and Safety Electronics Controller, the central electronic control unit of a Tesla vehicle). It is polled at this rate and does not wake the car when asleep or prevent the car from going to sleep. |
post_wake_poll_time |
number | 300 | >0 seconds | If the vehicle wakes up, it will be detected and the vehicle will be polled for data at a rate specified in poll_data_period for at least this number of seconds. After this, polling will fallback to a rate specified in poll_asleep_period . E.g. Suppose post_wake_poll_time =300, poll_data_period =60 and poll_asleep_period =120. In this case, when the care awakes, initially data will be polled each 60s for the first 300s. Then polling will continue each 120s. |
poll_data_period |
number | 60 | >0 seconds | The vehicle is polled every this parameter seconds after becoming awake for a period of post_wake_poll_time seconds. Note the vehicle can stay awake if this is set too short. |
poll_asleep_period |
number | 60 | >0 seconds | The vehicle is polled every this parameter seconds while being asleep and beyond the post_wake_poll_time after awakening. If set too short it can prevent the vehicle falling asleep. |
poll_charging_period |
number | 10 | >0 seconds | While charging, the car can be polled more frequently if desired using this parameter. |
ble_disconnected_min_time |
number | 300 | >0 seconds | Sensors will only be set to Unknown if the BLE connection remains disconnected for at least this time (useful if you have a slightly flakey BLE connection to your vehicle). Setting it to zero means sensors will be set to Unknown as soon as the BLE connection disconnects. |
fast_poll_if_unlocked |
number | 0 | 0, >0 | Controls whether fast polls are enabled when unlocked. If the vehicle is unlocked (and fast_poll_if_unlocked > 0) or a person is detected as present in the vehicle, the vehicle will be polled at update_interval until it is locked and/or no person is present in the vehicle. This could be useful if you wish to quickly detect a change in the vehicle (for example, I use it to detect when it is put into gear so I can trigger an automation to open my electric gate). Set to 0 to disable, any value > 0 to enable. |
wake_on_boot |
number | 0 | 0, >0 | Controls whether the car is woken when the board restarts. Set to 0 to not wake, any value > 0 to wake. |
Note that if the other parameters are not multiples of update_interval
, the timings will be longer than expected. For example, if update_interval
is set to 30s and poll_data_period
is set to 75s, then the effective poll_data_period
will be 90s.
By default the car reports miles, so this integration returns miles. In home assistant you can edit the sensor and select the preferred unit of measurement there.
Recommended path
Alternative
Recommended path
Use an appropriate BLE app on your phone (eg BLE Scanner) to scan for the BLE devices nearby (so be close to your car). You should see your car in the list of devices (its name will begin with an ‘S’) with the MAC address displayed.
Copy and rename secrets.yaml.example
to secrets.yaml
and update it with your WiFi credentials (wifi_ssid
and wifi_password
) and vehicle VIN (tesla_vin
) and BLE MAC adress (ble_mac_address
).
Alternative
Build the scanner in the ble-scanner.yml
file. Once built, it will start scanning and print out the MAC address of any Tesla vehicles found in the logs. Building does take some time.
The following is the original method. I have never tried this and I do not maintain the associated file. I therefore do not recommend this but have left it here in case there are any people left who still use it.
secrets.yaml.example
to secrets.yaml
and update it with your WiFi credentials (wifi_ssid
and wifi_password
) and vehicle VIN (tesla_vin
).tesla_ble_listener
package in packages/base.yml
by uncommenting the listener: !include listener.yml
line.Note: The vehicle must be in range and awake for the BLE MAC address to be discovered. If the vehicle is not awake, open the Tesla app and run any command
[00:00:00][D][tesla_ble_listener:044]: Parsing device: [CC:BB:D1:E2:34:F0]: BLE Device name 1
[00:00:00][D][tesla_ble_listener:044]: Parsing device: [19:8A:BB:C3:D2:1F]:
[00:00:00][D][tesla_ble_listener:044]: Parsing device: [19:8A:BB:C3:D2:1F]:
[00:00:00][D][tesla_ble_listener:044]: Parsing device: [F5:4E:3D:C2:1B:A0]: BLE Device name 2
[00:00:00][D][tesla_ble_listener:044]: Parsing device: [A0:B1:C2:D3:E4:F5]: S1a87a5a75f3df858C
[00:00:00][I][tesla_ble_listener:054]: Found Tesla vehicle | Name: S1a87a5a75f3df858C | MAC: A0:B1:C2:D3:E4:F5
Clean up your environment before the next step by disabling the tesla_ble_listener
package in packages/base.yml
and running
make clean
Recommended path
For an example ESPHome dashboard, see tesla-ble-example.yml
. Please always start from this. I strongly recommend building this using the ESPHome Device Builder add-on in Home Assistant as this makes building and re-building (eg for updates) much easier.
If you have limited experience with flashing ESP32 devices and want to get more familiar, check Lazy Tech Geek’s video https://www.youtube.com/watch?v=XMpNJgozF-c
Alternative
The following are instructions if you use make
. I have never used these so cannot vouch for their accuracy (as I said above, it’s far easier to use the ESPHome Device Builder add-on in Home Assistant). I welcome any feedback on improving/correcting these instructions - please raise an issue for it.
secrets.yaml.example
to secrets.yaml
and update it with your WiFi credentials (wifi_ssid
and wifi_password
) and vehicle details (ble_mac_address
and tesla_vin
)Build the image with ESPHome. Alternate boards are listed in the boards/
directory.
make compile BOARD=m5stack-nanoc6
Upload/flash the firmware to the board.
make upload BOARD=m5stack-nanoc6
After flashing, you can use the log command to monitor the logs from the device. The host suffix is the last part of the device name in the ESPHome dashboard (e.g. 5b2ac7
).
make logs HOST_SUFFIX=-5b2ac7
For updating your device, you can OTA update over local WiFi using the same host suffix:
make upload HOST_SUFFIX=-5b2ac7
Note: the make commands are just a wrapper around the
esphome
command. You can also use theesphome
commands directly if you prefer (e.g.esphome compile tesla-ble-m5stack-nanoc6.yml
)
secrets.yaml
file when prompted.secrets.yaml
is correct. IT IS ESSENTIAL THESE ARE CORRECT - YOUR CAR WILL NOT PAIR OTHERWISE.Note: if the popup does not appear, you may need to press “Pair BLE key” and tap your card again
[optional] Rename your key to “ESPHome BLE” to make it easier to identify