Skip to content

Instantly share code, notes, and snippets.

@duncansmart
Last active May 29, 2025 03:01
Show Gist options
  • Save duncansmart/8ce84b96426435f0e855ba9ffe814cef to your computer and use it in GitHub Desktop.
Save duncansmart/8ce84b96426435f0e855ba9ffe814cef to your computer and use it in GitHub Desktop.
Powershell script to download Tesla Powerwall data to a CSV file
###############################################################################
# Get a refresh token using something like https://chrome.google.com/webstore/detail/tesla-access-token-genera/kokkedfblmfbngojkeaepekpidghjgag
$REFRESH_TOKEN = 'your.token.here'
# Set as appropriate:
$startDate = [DateTime]::Parse('2023-04-01')
$csvFile = 'C:\temp\my powerwall data.csv'
###############################################################################
# Auth
$token = Invoke-RestMethod -Uri "https://auth.tesla.com/oauth2/v3/token" -Method Post -Body @{
grant_type = "refresh_token"
client_id = "ownerapi"
scope = "openid email offline_access"
refresh_token = $REFRESH_TOKEN
}
# Get site ids
$products = Invoke-RestMethod -Uri "https://owner-api.teslamotors.com/api/1/products" -Headers @{ Authorization = "Bearer $($token.access_token)" }
#$products.response | ft
[array]$site_ids = $products.response | where { $_.energy_site_id -ne $null } | select -ExpandProperty 'energy_site_id'
"Site IDs: $site_ids"
if (Test-Path $csvFile) {
$lastTimestamp = (Import-Csv -Path $csvFile | select -Last 1).timestamp
$startDate = [DateTime]$lastTimestamp
}
# Ensure local time
# > The format for the end_date parameter value is "yyyy-mm-ddThh:mm:ss-hh:mm".
# > Specify your local time zone offset for best clarity. Universal time is
# > accepted in the format "yyyy-mm-ddThh:mm:ssZ", but the time is converted
# > to your local time zone, which could also change the date."
# -- https://tesla-api.timdorr.com/energy-products/energy/history#get-api-1-energy_sites-site_id-calendar_history
$startDate = $startDate.ToLocalTime()
"Start date: $startDate"
for ($date = $startDate.Date; $date -le [DateTime]::Now.Date; $date = $date.AddDays(1)){
"Downloading {0:D}" -F $date
$end_date = $date.AddDays(1).AddMinutes(-1).ToString("yyyy-MM-ddTHH:mm:ssK")
# " $end_date"
foreach ($site_id in $site_ids) {
$url = "https://owner-api.teslamotors.com/api/1/energy_sites/$site_id/calendar_history?kind=power&end_date=" + [Uri]::EscapeDataString($end_date)
#" $url"
$data = Invoke-RestMethod -Uri $url -Headers @{ Authorization = "Bearer $($token.access_token)" }
[array]$records = $data.response.time_series |
# don't include potentially incomplete records from within last 5 mins
where { [DateTime]$_.timestamp -lt (Get-Date).AddMinutes(-5) -and [DateTime]$_.timestamp -gt $startDate }
$records | Export-Csv -Path $csvFile -NoTypeInformation -Append
" added $($records.Count) records"
}
}
@davidconf
Copy link

How could this be modified to download state of charge as well as the current fields?

And is it possible to get the fields that show the split of where battery discharge was used?

Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment