Access the Tesla API with Perl!

For several years, I spent much time writing code for the Raspberry Pi, including hardware level register C code so that we can use various Integrated Circuit chips and sensors with Perl.

A couple of years ago, I acquired much larger and much more expensive toy, an all-wheel drive, full auto-pilot Tesla Model-X SUV, so of course, I want to write Perl code to access and manipulate it.

In the ensuing two years, I developed several microcontroller-based devices for the car, including one that knows where the car is, and its battery charge and state, and dispslays this information via an LED light strip and an OLED screen inside of my garage, along with an audible alarm that sounds for 1/8th of a second every three seconds if the battery is below a certain threshold so I don't forget to plug the charger in.

The microcontroller speaks to a Raspberry Pi who's job it is to fetch data from the Tesla API for my car, and to present that data to the microconroller, over Wifi. The software on the Pi is of course written in Perl, but because I couldn't figure out how to write the Tesla API authentication mechanism in Perl, I used Tim Dorssers TeslaPy Python library, and wrapped it for those calls.

Not anymore! We can now talk to the Tesla API via Perl!

I've officially released Tesla::Vehicle, which inherits from my other new related distribution, Tesla::API.

Upon first attempt to fetch data from Tesla, we will generate a URL that you must browse through to in a browser, authenticate into your Tesla account, and then paste back the ensuing URL you are redirected to into the console. After that, all access tokens are automatically used and updated when needed. My software never has any access or knowledge of your Tesla account credentials, which is the way I wanted this designed.

Thereafter, it's clear sailing!

The documentation is pretty elaborate about what the software can do so please check it out. For Tesla::Vehicle, there are methods to access aggregate data, sections of the aggregate data, and for several specific attributes that I use myself, I've added methods for them directly. More will be added as time goes on.


  • Built-in initial access token generation code with prompts of instructions
  • Automatic access token renewal
  • Single method (api()) to access data from endpoints that don't yet have a direct method
  • Built in modifiable data cache (set to 2 second timeout by default) to reduce calls to Tesla for data already retrieved (cache can be disabled)
  • Consistent data return values... for data aggregate methods, all data is returned as a hash reference
  • Near feature complete; most data has at least an aggregate fetch method, many individual attributes have accessor methods
  • Ability to wake the car from sleep (wake()). For calls that require the car to be awake, you can set auto_wake and we'll wake the car ourselves (disabled by default)
  • Many Tesla API calls require a vehicle ID sent in. We do our best to get this ourselves, otherwise it can be sent into new() or id()

Todo: The main one is adding methods that allow control of the functionality of the car. The only one implemented thus far is wake(). I'll also be adding more direct attribute retrieval methods. For now, use the aggregate methods and pull the data out of the return values yourself. There are also a few minor issues, primarily related to the handling of Tesla API timeouts.

How 'bout some code and output:

use warnings;
use strict;

use Tesla::Vehicle;

my $car = Tesla::Vehicle->new(auto_wake => 1);

    "My Tesla account has my car registered with the name '%s'.\n",

    "My car is in gear %s and is currently going %d MPH and my odometer is %d\n",

    "My latitude is %f, longitide is %f, my heading is %d degrees and its using %.2f kWh/mile\n",

    "My dashcam is %s, sentry mode is %s and I %s currently near my vehicle\n",
    $car->sentry_mode ? 'enabled' : 'disabled',
    $car->user_present ? 'am' : 'am not'

    "My battery is at %d%%, and is %s charging at %.2f volts pulling %.2f Amps\n",
    $car->charging_state ? 'currently' : 'not',

if ($car->battery_level >= $car->charge_limit_soc) {
    print "The charger is connected but disabled due to set maximum charge level reached\n";

    "My steering wheel warmer is %s, passenger seat warmer is %s, and Bio Weapon mode is %s\n",
    $car->heater_steering_wheel ? 'on' : 'off',
    $car->heater_seat_passenger ? 'on' : 'off',
    $car->bioweapon_mode ? 'on' : 'off'

    "The temperature inside the car is %dC and outside it's %dC, and climate control is %s\n",
    $car->is_climate_on ? 'on' : 'off'


My Tesla account has my car registered with the name 'Dream machine'.

My car is in gear P and is currently going 0 MPH and my odometer is 49066

My latitude is XX.XXXXXX, longitide is -XXX.XXXXXX, my heading is 229 degrees and its using 0.00 kWh/mile

My dashcam is Unavailable, sentry mode is disabled and I am not currently near my vehicle

My battery is at 94%, and is currently charging at 0.00 volts pulling 0.00 Amps

The charger is connected but disabled due to set maximum charge level reached

My steering wheel warmer is off, passenger seat warmer is off, and Bio Weapon mode is off

The temperature inside the car is 17C and outside it's 13C, and climate control is off

berrybrew version 1.36 released!

I've released version 1.36 of berrybrew, the Perlbrew for Windows. I've also reached out to see how I can become part of the Strawberry Perl team to get back on track with the release of new Strawberry Perls.

If you have any information on the release procedure for Strawberry, or know anyone on that team I might be able to contact to get things moving forward again, please let me know.

This release contains one significant new feature, the ability to use Powershell as the shell when opening or using a Perl. In the UI, when you "Open" your current Perl, or "use" any Perl you have installed, if the "Use Powershell" option is checked, instead of a cmd.exe shell, you'll be presented with a Powershell one instead (same applies for the command line berrybrew use $version.


The other changes in this release enhance the unit testing infrastructure, and the tests themselves.

Other notable changes since my last blog post:

  • The berrybrew associate command now has an alias of assoc for fewer keystrokes
  • Better exception handling in several cases
  • Documentation clarifications
  • Removed the upgrade command. It's now recommended to use the Installer to manage upgrades
  • Fix issue when using berrybrew to manage file associations where arguments passed to perl were being handled incorrectly
  • Unit test infrastructure enhancements

berrybrew version 1.34 released!

I've released version 1.34 of berrybrew.

Notable changes:

  • UI elements now update on the fly, so all changes are reflected immediately
  • You can 'use' any version of installed Perl from the UI, which opens up a new CLI window set to use the selected version
  • You can now fetch the updated list of Strawberry Perls available through the UI
  • Cloning installed Perls as well as a myriad of other operations can now be done through the UI
  • The API has been updated so that internal objects are updated live-time. This makes having long-running processes possible
  • Build/Test infrastructure updates
  • Documentation updates
  • Minor bug fixes

I've just got a new full time job, programming in Perl... finally, after several years of looking for that perfect work environment. Some of it will be on Windows (which I haven't used except for developing berrybrew), so I'm actually looking forward to using my own software, especially how useful its become thanks to the new UI I've developed.

Happy Perling!


berrybrew version 1.33 released!

I've released berrybrew version 1.33. This version has significant enhancements, along with some bug fixes and handling of some uncaught exceptions. The changes reflect versions 1.30 to 1.33.

Major changes include:


  • Allows you to install, switch to, remove and use Strawberry Perls directly
  • Can now spawn a CLI window for any Perl you have installed
  • Allows you to spawn a CLI window for the currently active Perl
  • Provides access to modify several of the core configuration options (debug, file association etc)
  • Allows you to disable all berrybrew Perls and restore to system default


  • Performs an upgrade on any previous berrybrew install
  • Adds any new configuration options, while preserving the values of any previously set existing ones
  • Provides facility to install the most recent version of Strawberry Perl
  • Allows you to have berrybrew manage the .pl file association
  • Allows you to have the UI run at system startup
  • Aborts if trying to install the same version that's already installed


  • You can now leave off the 32/64 bit prefix on a Perl name, and we'll default to _64
  • All execution paths return a proper exit code
  • Added new berrybrew hidden command, lists all, well, hidden commands

For all other changes, please refer to the Changes file.



berrybrew, the Perlbrew for Windows 1.30 released

Merry Christmas fellow Perlers!

I have been working tirelessly on the newest version of berrybrew, and thought there's no better day to release it.

It brings significant new features:

New Features

  • Added a UI, runs out of the System Tray, allows installing, removing and switching Perls using a button
  • Added new associate command, allowing berrybrew to manage .pl file associations
  • Added berrybrew-refresh command, to be run after switching perls. No more having to re-open command line windows
  • If a newer point release of a major version is introduced, we now seamlessly integrate installed previous point-releases into the Perls available
  • Configuration options are now based in the Windows Registry
  • Added new options command, allows changing configuration options at runtime
  • We now supply a bb command, which is simply a short-hand form for berrybrew
  • Greatly enhanced the self-extracting installer
  • Much more precise handling of the PATH environment variable
  • More graceful handling of exceptions
  • Added info command which displays various internal directory path information
  • Added new hidden/developer commands


The UI is automatically installed by the installer. It starts and resides hidden in the System Tray until it is needed. Simply click the berrybrewUI icon to bring up a Windows Form window. You can install, remove and switch between Perl instances.

When switching Perls using the UI, if you have open CLI windows, you still need to run berrybrew-refresh or open a new CLI window to refresh the path information.

To exit the berrybrewUI, right-click on the System Tray icon, and click Exit.


There are several enhancements to the installer:

  • We properly check for existing installations, and ask confirmation questions on the actions, depending on information about the previous install. In some cases, we'll ask to do a direct upgrade, in others, we'll ask if we can simply disable the old version before installing the new. See caveats below.

  • We now ask for the directory location of the Perl instance directory (internally referred to as root_dir). If you specify a location that a previous berrybrew used, we'll merrily inherit all of the previously installed Perls.

  • Uninstall is available through Add/Remove programs

  • UI provides select-able options to 1) install the most recent version of Perl, 2) start the UI at system startup, 3) allow berrybrew to manage .pl file association

Caveats: If you have a previous version of berrybrew where you've changed any of the default configuration variables in the config.json file, you will have to manually update these options after install of the new version. Simply run berrybrew options on the new version to see what values are set. Then, open up your previous berrybrew's config.json file, and for each difference, simply run berrybrew options directive value where directive is the name of the option, and value is the value from the old config file. This will be automated in a future release.

File Association

You can now allow berrybrew to manage the .pl file association. We implement this in a similar way to Unix, in which when we're managing this association, the system will use the first perl found in the PATH environment variable.

  • Check current file association with berrybrew associate
  • Allow us to manage the association: berrybrew associate set
  • Revert back to the previous association: berrybrew associate unset

Development Information

  • Broke out the dev build script into three: build_api.bat, build_binary.bat and build_ui.bat. Left in place the build.bat script, which performs all three actions
  • The dev and test builds automatically create and use their own respective registry locations (HKLM\Software\berrybrew-build and HKLM\Software\berrybrew-test)