Beefy Boxes and Bandwidth Generously Provided by pair Networks
laziness, impatience, and hubris
 
PerlMonks  

I have finally done it; wrote a Tesla API library for Perl!

by stevieb (Canon)
on Mar 18, 2022 at 22:20 UTC ( #11142245=perlnews: print w/replies, xml ) Need Help??

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.

Features:

  • 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); printf( "My Tesla account has my car registered with the name '%s'.\n", $car->name ); printf( "My car is in gear %s and is currently going %d MPH and my odomete +r is %d\n", $car->gear, $car->speed, $car->odometer ); printf( "My latitude is %f, longitide is %f, my heading is %d degrees and +its using %.2f kWh/mile\n", $car->latitude, $car->longitude, $car->heading, $car->power ); printf( "My dashcam is %s, sentry mode is %s and I %s currently near my ve +hicle\n", $car->dashcam, $car->sentry_mode ? 'enabled' : 'disabled', $car->user_present ? 'am' : 'am not' ); printf( "My battery is at %d%%, and is %s charging at %.2f volts pulling % +.2f Amps\n", $car->battery_level, $car->charging_state ? 'currently' : 'not', $car->charger_voltage, $car->charge_actual_current ); if ($car->battery_level >= $car->charge_limit_soc) { print "The charger is connected but disabled due to set maximum ch +arge level reached\n"; } printf( "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' ); printf( "The temperature inside the car is %dC and outside it's %dC, and c +limate control is %s\n", $car->temperature_inside, $car->temperature_outside, $car->is_climate_on ? 'on' : 'off' );

Output:

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 49 +066 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 curren +tly 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 climat +e control is off

Replies are listed 'Best First'.
Re: I have finally done it; wrote a Tesla API library for Perl!
by perldigious (Priest) on Mar 18, 2022 at 22:37 UTC

    I've always loved to see your passion for these sorts of things, stevieb. Of course now I'm waiting for the plot twist where your local highway patrol use your own $car->speed data to hold up a speeding ticket you're contesting in court. ;-)

    Just another Perl hooker - My clients appreciate that I keep my code clean but my comments dirty.

      I wrote Mock::Sub several years ago, apparently waiting for this exact problem!

      use warnings; use strict; use feature 'say'; use Mock::Sub; use Tesla::Vehicle; my $mock = Mock::Sub->new; my $car = Tesla::Vehicle->new; my $speed_sub = $mock->mock('Tesla::Vehicle::speed'); $speed_sub->return_value(60); # No matter how fast I'm going, we'll always return 60! say $car->speed;

        In that instance was it best designated as Mock::Sub, or should it have been designated Mock::HighwayPatrol? :-)

        Just another Perl hooker - My clients appreciate that I keep my code clean but my comments dirty.
Re: I have finally done it; wrote a Tesla API library for Perl!
by roboticus (Chancellor) on Mar 23, 2022 at 13:19 UTC

    stevieb:

    I normally don't like to make a comment where I don't have anything to contribute....

    But this is pretty freakin' awesome! Maybe I'll have to keep my eyes open for a Tesla when it's time for my next car. (Though, I *do* enjoy my Fiesta!)

    ...roboticus

    When your only tool is a hammer, all problems look like your thumb.

      Maybe I'll have to keep my eyes open for a Tesla when it's time for my next car.

      I prefer having a car that does not dump loads of snow into the trunk. ;-)

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

        My Model-X is designed differently than that. It's a hatchback SUV with a far different (ie. better) design. The only thing I don't like about my car is that it has falcon wings. They're a pain in the ass sometimes. I'm sure they were put on the car solely for the "Wow!" factor at the auto shows.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlnews [id://11142245]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others contemplating the Monastery: (6)
As of 2023-02-03 14:13 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    I prefer not to run the latest version of Perl because:







    Results (26 votes). Check out past polls.

    Notices?