TMC is an independent, primarily volunteer organization that relies on ad revenue to cover its operating costs. Please consider whitelisting TMC on your ad blocker and becoming a Supporting Member. For more info: Support TMC

Model S REST API

Discussion in 'Model S: User Interface' started by timdorr, Feb 2, 2013.

  1. Zas

    Zas Sig. Performance #2113

    Joined:
    Dec 24, 2012
    Messages:
    177
    Location:
    Toronto
    I like the challenge !.... i will try it out - thanks
     
  2. aviators99

    aviators99 Model S - R140

    Joined:
    Jan 1, 2010
    Messages:
    1,458
    Location:
    Weston, Florida, United States
    Also, note that as written, it won't necessarily work if you have more than one vehicle on your account. It would be a relatively simple change to fix that, but until someone asks, I figured I wouldn't bother.

    - - - Updated - - -

    On what sort of machine will you be trying it?
     
  3. Zas

    Zas Sig. Performance #2113

    Joined:
    Dec 24, 2012
    Messages:
    177
    Location:
    Toronto
    I have only one Model S, for now :)

    and i will likely try it out on either Red Hat, or just a Mac OSX
     
  4. iridium

    iridium Member

    Joined:
    Jul 10, 2012
    Messages:
    176
    Location:
    Scottsdale, AZ
    Is there really no client auth?
     
  5. hans

    hans P631

    Joined:
    Sep 27, 2012
    Messages:
    1,132
    Location:
    Menlo Park
    There is client auth. Not sure how you got that idea. You need to authenticate with your teslamotors.com login and password and then use the cookie that it returns for all subsequent requests.
     
  6. XrstalLens

    XrstalLens Model S P1327 VIN P01867

    Joined:
    Dec 30, 2011
    Messages:
    115
    Location:
    Kirkland, WA
    For Windows users, here is a pretty simple PowerShell script that allows access to the car. This version requires PS 3.0 (because it uses Invoke-RestMethod), which is installed by default on Windows 8 and Windows Server 2012, but can also be installed on Windows 7. If you save it as Tesla.ps1, for example, then you can lock your car by running ".\Tesla.ps1 -Lock". You can put in your username and password at line 44, or you can have it ask for them by specifying the -Credentials switch.
    Code:
    param([switch]$Credentials,
          [switch]$TestUrl,
          [switch]$ClimateOn,
          [switch]$ClimateOff,
          [switch]$Lock,
          [switch]$Unlock,
          [switch]$CloseSunroof,
          [switch]$StopCharge,
          [switch]$StartCharge
    )
    $ErrorActionPreference = "Stop"
    Set-StrictMode -Version 2.0
    $m_ts = $null
    $m_carID = 0
    function InvokeCarCommand($command, $successtext, $failtext)
    {
        $resp = Invoke-RestMethod -Uri "$uriRoot/vehicles/$m_carID/command/$command" -Method GET -WebSession $m_ts
        if ($resp.result -eq "true") {
            Write-Output $successtext
        }
        else {
            Write-Output "Unable to ${failtext}. Reason returned: `"$($resp.reason)`""
        }
    }
    if ($TestUrl) {
        $uriRoot = "[URL]http://timdorr.apiary.io[/URL]"
    }
    else {
        $uriRoot = "[URL]https://portal.vn.teslamotors.com[/URL]"
    }
    if ($Credentials) {
        $creds = Get-Credential
        $plaintextpwd = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR($creds.Password))
        $credsjson = @{ "user_session[email]" = "$($creds.UserName)"; "user_session[password]" = "$plaintextpwd" }
    }
    else {
        $credsjson = @{ "user_session[email]" = "[EMAIL="[email protected]"][email protected][/EMAIL]"; "user_session[password]" = "MyPassword" }
    }
    # Login and establish session
    $r = Invoke-RestMethod -Uri "$uriRoot/login" -Method GET -SessionVariable m_ts
    # We ignore the return form.
    $r = Invoke-RestMethod -Uri "$uriRoot/login" -Method POST -WebSession $m_ts -Body $credsjson
    # Now, get the vehicle information
    $vehicle = Invoke-RestMethod -Uri "$uriRoot/vehicles" -Method GET -WebSession $m_ts
    if ($vehicle.Count -gt 1) {
        Write-Output "You have multiple vehicles:"
        $i = 1
        foreach ($entry in $vehicle) {
            $entry | Add-Member -NotePropertyName "Index" -NotePropertyValue $i -Force
            $i++
        }
        $vehicle | Select-Object -Property Index,display_name,vin,state | Format-Table -Auto
        $resp = Read-Host "Enter the index of the vehicle you wish to control"
        $value = -1
        if (-not [Int32]::TryParse($resp, [ref]$value)) {
            throw "Entered value is not a valid number."
        }
        if (($value -lt 1) -or ($value -gt $vehicle.Count)) {
            throw "Invalid entry selected."
        }
        $vehicle = $vehicle[$value - 1]
    }
    else {
        Write-Output "Controlling vehicle $($vehicle.vin)."
    }
    $script:m_carID = $vehicle.id
    $mobileEnabled = Invoke-RestMethod -Uri "$uriRoot/vehicles/$m_carID/mobile_enabled" -Method GET -WebSession $m_ts
    if ($mobileEnabled.result -ne "true") {
        throw "Mobile access is not enabled on the vehicle. Please enable it through the console of the vehicle and try again."
    }
    $physical_state = Invoke-RestMethod -Uri "$uriRoot/vehicles/$m_carID/command/vehicle_state" -Method GET -WebSession $m_ts
    $climate_state = Invoke-RestMethod -Uri "$uriRoot/vehicles/$m_carID/command/climate_state" -Method GET -WebSession $m_ts
    $charge_state = Invoke-RestMethod -Uri "$uriRoot/vehicles/$m_carID/command/charge_state" -Method GET -WebSession $m_ts
    Write-Output "Current Vehicle State (before executing any commands):"
    $physical_state | Select-Object -Property locked,sun_roof_percent_open,car_version,df,dr,pf,pr,ft,rt | Format-Table -Auto
    $climate_state | Select-Object -Property inside_temp,outside_temp,fan_status,is_auto_conditioning_on | Format-Table -Auto
    $charge_state | Select-Object -Property charging_state,battery_range,battery_level,charger_voltage,charger_actual_current,charger_power,time_to_full_charge,charge_rate | Format-Table -Auto
    if ($ClimateOn) {
        InvokeCarCommand "auto_conditioning_start" "Climate control turned on." "turn on climate control"
    }
    if ($ClimateOff) {
        InvokeCarCommand "auto_conditioning_stop" "Climate control turned off." "turn off climate control"
    }
    if ($Lock) {
        InvokeCarCommand "door_lock" "Doors are locked." "lock doors"
    }
    if ($Unlock) {
        InvokeCarCommand "door_unlock" "Doors are unlocked." "unlock doors"
    }
    if ($CloseSunroof) {
        InvokeCarCommand "sun_roof_control?state=close" "Sunroof is closed." "close sunroof"
    }
    if ($StopCharge) {
        InvokeCarCommand "charge_stop" "Charging has been stopped." "stop charging"
    }
    if ($StartCharge) {
        InvokeCarCommand "charge_start" "Charging has been started." "start charging"
    }
    
     
  7. Zas

    Zas Sig. Performance #2113

    Joined:
    Dec 24, 2012
    Messages:
    177
    Location:
    Toronto
    Got it to work !.. but I didnt get any email when not plugged in ?.. when i had my car plugged in .. and it came back "car plugged in".. and when i unplugged it, it states "Not plugged inNull message body; hope that's ok"..but no email ?

    another question, how this script 'install' into the car , so that in the future it auto-emails me ?.. or how does it work in general , as surely, its not a script you would run every time manually.
     
  8. ClaytonTMC

    ClaytonTMC Member

    Joined:
    Jan 28, 2013
    Messages:
    17
    Location:
    Los Altos, CA
     
  9. iridium

    iridium Member

    Joined:
    Jul 10, 2012
    Messages:
    176
    Location:
    Scottsdale, AZ
    I was expecting to have to include some type of token identifying the app, the developer, etc. You see some models where you register as a developer and then get a token which is included in API calls in addition to the user auth.

    So if someone gets my website credentials they can view/change my car?
     
  10. markb1

    markb1 Active Member

    Joined:
    Feb 17, 2012
    Messages:
    2,688
    Location:
    San Diego, CA
    Even if they required developers to register, anyone with your website credentials could download the official app and access your car.
     
  11. aviators99

    aviators99 Model S - R140

    Joined:
    Jan 1, 2010
    Messages:
    1,458
    Location:
    Weston, Florida, United States
    It's one of two things: 1) You don't have mail configured on that machine. 2) It's going into your spam. Mine went into spam until I added the address to my contacts. Check your spam, or try messing around with the command line Mail by hand until you successfully get a message through.

    You won't be able to install it in the car. You'll need to use cron on the Unix machine to run the script at the time you want.

    Good job, by the way.
     
  12. SigS905

    SigS905 Sig S 905 + X 5

    Joined:
    May 9, 2012
    Messages:
    200
    Location:
    FV, CA
    #72 SigS905, Feb 11, 2013
    Last edited: Feb 12, 2013
    Modified aviators99 script. I now have a cron script so I can plug in as soon as I get home and within 5 miutes, charging will stop and recommence at midnight.

    Code:
    #! /bin/sh
    
    HOME_DIRECTORY="HOMEDIR"
    # Tesla Fashion Island 33.62 -117.90
    HOME_LATITUDE=33
    HOME_LATITUDE_FRACTION=62
    HOME_LONGITUDE=-117
    HOME_LONGITUDE_FRACTION=90
    TM_USERNAME="USERNAME"
    TM_PASSWORD="PASSWORD"
    ALERT_EMAIL="EMAILADDRESS"
    
    curl -s --cookie $HOME_DIRECTORY/cookie.jar -c $HOME_DIRECTORY/cookie.jar -X POST -F "user_session[email]=$TM_USERNAME" -F "user_session[password]=$TM_PASSWORD" -k "https://portal.vn.teslamotors.com/login" > /dev/null 2>&1
    
    vehicle=`curl -s --cookie $HOME_DIRECTORY/cookie.jar -c $HOME_DIRECTORY/cookie.jar -k "https://portal.vn.teslamotors.com/vehicles" | awk -F, '{for(i=1;i<NF;i++){if($i ~ /"id":.*/) {print  substr($i,6)} }}'`
    
    if [ "$vehicle" == "" ]; then
    #   echo "Could not communicate with vehicle"
       exit 0
    fi
    
    ps=`curl -s --cookie $HOME_DIRECTORY/cookie.jar -c $HOME_DIRECTORY/cookie.jar -k "https://portal.vn.teslamotors.com/vehicles/$vehicle/command/charge_state" | awk -F, '{for(i=1;i<NF;i++) {if($i ~ /".*pilot_current":.*/) {print substr($i,25)} }}'`
    
    if [ "$ps" == "" ]; then
    #   echo "Could not communicate with vehicle"
       exit 0
    fi
    
    if [ "$ps" == "0" ]; then
    #   echo "Not plugged in"
    #   Mail -s 'Car not plugged in!' $ALERT_EMAIL < /dev/null
       exit 1
    fi
    
    cs=`curl -s --cookie $HOME_DIRECTORY/cookie.jar -c $HOME_DIRECTORY/cookie.jar -k "https://portal.vn.teslamotors.com/vehicles/$vehicle/command/charge_state" | awk -F, '{for(i=1;i<NF;i++) {if($i ~ /".*charging_state":.*/) {print substr($i,19)} }}'`
    #echo "Charging state = $cs"
    lat=`curl -s --cookie $HOME_DIRECTORY/cookie.jar -c $HOME_DIRECTORY/cookie.jar -k "https://portal.vn.teslamotors.com/vehicles/$vehicle/command/drive_state" | awk -F, '{for(i=1;i<NF;i++) {if($i ~ /".*latitude":.*/) {print substr($i,12)} }}'`
    cur_lat=`echo $lat | sed -e 's/\./ /g' | awk '{print $1}'`
    cur_lat_frac=`echo $lat | sed -e 's/\./ /g' | awk '{print substr($2,0,2)}'`
    long=`curl -s --cookie $HOME_DIRECTORY/cookie.jar -c $HOME_DIRECTORY/cookie.jar -k "https://portal.vn.teslamotors.com/vehicles/$vehicle/command/drive_state" | awk -F, '{for(i=1;i<NF;i++) {if($i ~ /".*longitude":.*/) {print substr($i,13)} }}'`
    cur_long=`echo $long | sed -e 's/\./ /g' | awk '{print $1}'`
    cur_long_frac=`echo $long | sed -e 's/\./ /g' | awk '{print substr($2,0,2)}'`
    #echo "Current location = $cur_lat.$cur_lat_frac ($lat) $cur_long.$cur_long_frac ($long)"
    cur_hour=$(date "+%k")
    cur_min=$(date "+%M")
    #echo "Plugged in $cur_hour:$cur_min"
    if (( ($HOME_LATITUDE == $cur_lat && $HOME_LATITUDE_FRACTION == $cur_lat_frac) && ($HOME_LONGITUDE == $cur_long && $HOME_LONGITUDE_FRACTION == $cur_long_frac) )); then
    #    echo "Parked at home"
        if (( $cur_hour > 5 && $cur_hour < 24 )); then
            if [ "$cs" == "\"Charging\"" ]; then
    #            echo "Charging stopped due to high rates"
                cs=`curl -s --cookie $HOME_DIRECTORY/cookie.jar -c $HOME_DIRECTORY/cookie.jar -k "https://portal.vn.teslamotors.com/vehicles/$vehicle/command/charge_stop"`
            fi
        elif [ "$cs" == "\"Stopped\"" ]; then
    #            echo "Charging started at optimal rates"
                cs=`curl -s --cookie $HOME_DIRECTORY/cookie.jar -c $HOME_DIRECTORY/cookie.jar -k "https://portal.vn.teslamotors.com/vehicles/$vehicle/command/charge_start"`
        fi
    fi
    
    
    Modified the script to only work when the car is at home. Set your HOME_LATITUDE, HOME_LATITUDE_FRACTION (2 digits) and HOME_LONGITUDE, HOME_LONGITUDE_FRACTION (2 digits) to your home coordinates.

    Started a cron job with "crontab -e" and added the following entry:
    0-59/5 * * * * /path/to/script
     
  13. Zas

    Zas Sig. Performance #2113

    Joined:
    Dec 24, 2012
    Messages:
    177
    Location:
    Toronto
    ohhh.. so i have to run the script manually each time ?.. that reduces its 'coolness' :( its super fun to be able to communicate with the car with some coding - i can see a bright future with some killer customized apps !!
     
  14. widodh

    widodh Model S 85 and 100D

    Joined:
    Jan 23, 2011
    Messages:
    6,051
    Location:
    Middelburg, The Netherlands
    Yes, you have to execute the script on a machine. It doesn't run automagically.
     
  15. 4sevens.com

    4sevens.com Member

    Joined:
    Aug 20, 2012
    Messages:
    418
    ^ you can run it as a cron job

    Any way to get the lat/lon coordiates?
     
  16. aviators99

    aviators99 Model S - R140

    Joined:
    Jan 1, 2010
    Messages:
    1,458
    Location:
    Weston, Florida, United States
    No, you don't have to run manually. cron is a program that will run any script at the time you want, or how often you want.
     
  17. jcstp

    jcstp Active Member

    Joined:
    Feb 7, 2011
    Messages:
    1,627
    Location:
    Belgium
    If someone made an app via PhoneGap | Home it would be available for all platforms!
     
  18. widodh

    widodh Model S 85 and 100D

    Joined:
    Jan 23, 2011
    Messages:
    6,051
    Location:
    Middelburg, The Netherlands
    Yes, I should have made myself more clear.

    I'm a Linux sysadmin as my daily job and we sometimes see things different.

    But yes, you should run this script using CRON or something like that. Just wanted to point out that it's not a daemon :)
     
  19. SigS905

    SigS905 Sig S 905 + X 5

    Joined:
    May 9, 2012
    Messages:
    200
    Location:
    FV, CA
    See my thread above (#72). It shows how to get latitude and longitude and it will charge the car from midnight to 6 am when at home.
     
  20. aviators99

    aviators99 Model S - R140

    Joined:
    Jan 1, 2010
    Messages:
    1,458
    Location:
    Weston, Florida, United States
    Here's the output from a webpage I created for my friends to keep track of me:

    mypage.jpg
     

Share This Page

  • About Us

    Formed in 2006, Tesla Motors Club (TMC) was the first independent online Tesla community. Today it remains the largest and most dynamic community of Tesla enthusiasts. Learn more.
  • Do you value your experience at TMC? Consider becoming a Supporting Member of Tesla Motors Club. As a thank you for your contribution, you'll get nearly no ads in the Community and Groups sections. Additional perks are available depending on the level of contribution. Please visit the Account Upgrades page for more details.


    SUPPORT TMC