The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.

NAME

Tesla::API - Interface to Tesla's API

Coverage Status

SYNOPSIS

    use Tesla::API;

    my $tesla = Tesla::API->new;

    my @endpoint_names = keys %{ $tesla->endpoints };

    # See Tesla::Vehicle for direct access to vehicle-related methods

    my $endpoint_name   = 'VEHICLE_DATA';
    my $vehicle_id      = 3234234242124;

    my $car_data = $tesla->api($endpoint_name, $vehicle_id);

    if ($tesla->api('ACTUATE_TRUNK', $vehicle_id, {which_trunk => 'rear'})) {
        put_stuff_in_trunk();
    }

DESCRIPTION

This distribution provides access to the Tesla API.

WARNING: This is an initial, beta release. The interface may change.

This class is designed to be subclassed. For example, I have already begun a new Tesla::Vehicle distribution which will have access and update methods that deal specifically with Tesla autos, then a Tesla::Powerwall distribution for their battery storage etc.

METHODS

new(%params)

Instantiates and returns a new Tesla::API object.

NOTE: When instantiating an object and you haven't previously authenticated, a URL will be displayed on the console for you to navigate to. You will then be redirected to Tesla's login page where you will authenticate. You will be redirected again to a "Page Not Found" page, in which you must copy the URL from the address bar and paste it back into the console.

We then internally generate an access token for you, store it in a tesla_cache.json file in your home directory, and use it on all subsequent accesses.

NOTE: If you do not have a Tesla account, you can still instantiate a Tesla::API object by supplying the unauthenticated => 1 parameter to new().

Parameters:

All parameters are to be sent in the form of a hash.

    unauthenticated

Optional, Bool: Set to true to bypass the access token generation.

Default: undef

    api_cache_time

Optional, Integer: By default, we cache the fetched data from the Tesla API for two seconds. If you make calls that have already been called within that time, we will return the cached data.

Send in the number of seconds you'd like to cache the data for. A value of zero (0) will disable caching and all calls through this library will go directly to Tesla every time.

Return: Integer, the number of seconds we're caching Tesla API data for.

api($endpoint, $id, $api_params)

Responsible for disseminating the endpoints and retrieving data through the Tesla API.

Parameters:

    $endpoint

Mandatory, String: A valid Tesla API endpoint name. The entire list can be found in the t/test_data/endpoints.json file for the time being.

    $id

Optional, Integer: Some endpoints require an ID sent in (eg. vehicle ID, Powerwall ID etc).

    $api_params

Optional, Hash Reference: Some API calls require additional parameters. Send in a hash reference where the keys are the API parameter name, and the value is, well, the value.

Return: Hash or array reference, depending on the endpoint.

api_cache_clear

Some methods chain method calls. For example, calling $vehicle->doors_lock will poll the API, then cache the state data.

if another call is made to $vehicle->locked immediately thereafter to check whether the door is actually closed or not, the old cached data would normally be returned.

If we don't clear the cache out between these two calls, we will be returned stale data.

Takes no parameters, has no return. Only use this call in API calls that somehow manipulate the state of the object you're working with.

api_cache_time($cache_seconds)

The number of seconds we will cache retrieved endpoint data from the Tesla API for, to reduce the number of successive calls to retrieve the same data.

Parameters:

    $cache_seconds

Optional, Integer: By default, we cache the fetched data from the Tesla API for two seconds. If you make calls that have already been called within that time, we will return the cached data.

Send in the number of seconds you'd like to cache the data for. A value of zero (0) will disable caching and all calls through this library will go directly to Tesla every time.

Return: Integer, the number of seconds we're caching Tesla API data for.

object_data

Returns a hash reference of the data we've collected for you and stashed within the object. This does not reflect the entire object, just the data returned from Tesla's API.

endpoints

Returns a hash reference of hash references. Each key is the name of the endpoint, and its value contains data on how we process the call to Tesla.

Example (snipped for brevity):

    {
        MEDIA_VOLUME_DOWN => {
            TYPE => 'POST',
            URI => 'api/1/vehicles/{vehicle_id}/command/media_volume_down'
            AUTH => $VAR1->{'UPGRADES_CREATE_OFFLINE_ORDER'}{'AUTH'},
        },
        VEHICLE_DATA => {
            TYPE => 'GET',
            URI => 'api/1/vehicles/{vehicle_id}/vehicle_data',
            AUTH => $VAR1->{'UPGRADES_CREATE_OFFLINE_ORDER'}{'AUTH'}
        },
    }

Bracketed names in the URI (eg: {vehicle_id}) are variable placeholders. It will be replaced with the ID sent in to the various method or api() call.

To get a list of endpoint names:

    my @endpoint_names = keys %{ $tesla->endpoints };

mech

Returns the WWW::Mechanize object we've instantiated internally.

EXAMPLE USAGE

See Tesla::Vehicle for vehicle specific methods.

    use Data::Dumper;
    use Tesla::API;
    use feature 'say';

    my $tesla = Tesla::API->new;
    my $vehicle_id = 1234238782349137;

    print Dumper $tesla->api('VEHICLE_DATA', $vehicle_id);

Output (massively and significantly snipped for brevity):

    $VAR1 = {
        'vehicle_config' => {
            'car_type' => 'modelx',
            'rear_seat_type' => 7,
            'rear_drive_unit' => 'Small',
            'wheel_type' => 'Turbine22Dark',
            'timestamp' => '1647461524710',
            'rear_seat_heaters' => 3,
            'trim_badging' => '100d',
            'headlamp_type' => 'Led',
            'driver_assist' => 'TeslaAP3',
        },
        'id_s' => 'XXXXXXXXXXXXXXXXX',
        'vehicle_id' => 'XXXXXXXXXX',
        'charge_state' => {
            'usable_battery_level' => 69,
            'battery_range' => '189.58',
            'charge_limit_soc_std' => 90,
            'charge_amps' => 48,
            'charge_limit_soc' => 90,
            'battery_level' => 69,
        },
        'vin' => 'XXXXXXXX',
        'in_service' => $VAR1->{'vehicle_config'}{'use_range_badging'},
        'user_id' => 'XXXXXX',
        'id' => 'XXXXXXXXXXXXX',
        'drive_state' => {
            'shift_state' => 'P',
            'heading' => 92,
            'longitude' => '-XXX.XXXXXX',
            'latitude' => 'XX.XXXXXX',
            'power' => 0,
            'speed' => undef,
        },
        'api_version' => 34,
        'display_name' => 'Dream machine',
        'state' => 'online',
        'access_type' => 'OWNER',
        'option_codes' => 'AD15,MDL3,PBSB,RENA,BT37,ID3W,RF3G,S3PB,DRLH,DV2W,W39B,APF0,COUS,BC3B,CH07,PC30,FC3P,FG31,GLFR,HL31,HM31,IL31,LTPB,MR31,FM3B,RS3H,SA3P,STCP,SC04,SU3C,T3CA,TW00,TM00,UT3P,WR00,AU3P,APH3,AF00,ZCST,MI00,CDM0',
        'vehicle_state' => {
            'valet_mode' => $VAR1->{'vehicle_config'}{'use_range_badging'},
            'vehicle_name' => 'Dream machine',
            'sentry_mode_available' => $VAR1->{'vehicle_config'}{'plg'},
            'sentry_mode' => $VAR1->{'vehicle_config'}{'use_range_badging'},
            'car_version' => '2022.4.5.4 abcfac6bfcdc',
            'homelink_device_count' => 3,
            'is_user_present' => $VAR1->{'vehicle_config'}{'use_range_badging'},
            'odometer' => 'XXXXXXX.233656',
            'media_state' => {
                'remote_control_enabled' => $VAR1->{'vehicle_config'}{'plg'}
            },
        },
        'autopark_style' => 'dead_man',
        'software_update' => {
            'expected_duration_sec' => 2700,
            'version' => ' ',
            'status' => '',
            'download_perc' => 0,
            'install_perc' => 1
        },
        'speed_limit_mode' => {
            'max_limit_mph' => 90,
            'min_limit_mph' => '50',
            'active' => $VAR1->{'vehicle_config'}{'use_range_badging'},
            'current_limit_mph' => '80.029031',
            'pin_code_set' => $VAR1->{'vehicle_config'}{'plg'}
        },
        'climate_state' => {
               'passenger_temp_setting' => '20.5',
               'driver_temp_setting' => '20.5',
               'side_mirror_heaters' => $VAR1->{'vehicle_config'}{'use_range_badging'},
               'is_climate_on' => $VAR1->{'vehicle_config'}{'use_range_badging'},
               'fan_status' => 0,
               'seat_heater_third_row_right' => 0,
               'seat_heater_right' => 0,
               'is_front_defroster_on' => $VAR1->{'vehicle_config'}{'use_range_badging'},
               'battery_heater' => $VAR1->{'vehicle_config'}{'use_range_badging'},
               'is_rear_defroster_on' => $VAR1->{'vehicle_config'}{'use_range_badging'},
        },
        'gui_settings' => {
              'gui_temperature_units' => 'C',
              'gui_charge_rate_units' => 'km/hr',
              'gui_24_hour_time' => $VAR1->{'vehicle_config'}{'use_range_badging'},
              'gui_range_display' => 'Ideal',
              'show_range_units' => $VAR1->{'vehicle_config'}{'plg'},
              'gui_distance_units' => 'km/hr',
              'timestamp' => '1647461524710'
        }
    };

AUTHOR

Steve Bertrand, <steveb at cpan.org>

ACKNOWLEDGEMENTS

This distribution suite has been a long time in the works. For my other projects written in Perl previous to writing this code that required data from the Tesla API, I wrapped Tim Dorssers wonderful TeslaPy Python project.

Much of the code in this distribution is heavily influenced by the code his project, and currently, we're using a direct copy of its Tesla API endpoint file.

Thanks Tim, and great work!

Also thanks goes out to https://teslaapi.io, as a lot of the actual request parameter information and response data layout I learned from that site while implementing the actual REST calls to the Tesla API.

LICENSE AND COPYRIGHT

Copyright 2022 Steve Bertrand.

This program is free software; you can redistribute it and/or modify it under the terms of the the Artistic License (2.0). You may obtain a copy of the full license at:

http://www.perlfoundation.org/artistic_license_2_0

The copied endpoint code data borrowed from Tim's TeslaPy project has been rebranded with the Perl license here, as permitted by the MIT license TeslaPy is licensed under.