A Python module to use the Tesla Motors Owner API for monitoring and controlling Tesla vehicles, Powerwall batteries, and solar panels remotely
—
Quality
Pending
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Utility functions for data processing, unit conversion, VIN decoding, option code lookup, and error handling with custom exception classes for Tesla API interactions.
Enhanced dictionary class with pretty-printing capabilities for JSON data representation.
class JsonDict(dict):
"""Pretty printing dictionary with JSON string representation."""
def __str__(self):
"""
Serialize dict to JSON formatted string with indents.
Returns:
str: JSON formatted string with 4-space indentation
"""Custom exception classes for handling Tesla API-specific errors and vehicle/product operation failures.
class VehicleError(Exception):
"""
Vehicle-specific exception class.
Raised when vehicle commands fail or vehicle operations cannot be completed.
Common scenarios include commands returning False result, vehicle not responding,
or user not present for media commands.
"""
class ProductError(Exception):
"""
Product-specific exception class.
Raised when energy product (Powerwall/solar) commands fail or operations
cannot be completed, typically when response code is not 201.
"""Comprehensive VIN decoding functionality that extracts detailed vehicle specifications from the Vehicle Identification Number.
def decode_vin(self):
"""
Decode vehicle identification number to detailed specification dictionary.
Returns:
JsonDict: Decoded VIN information containing:
- manufacturer (str): 'Tesla Motors, Inc.'
- make (str): Tesla model (e.g., 'Tesla Model 3')
- body_type (str): Body style and handedness
- belt_system (str): Seatbelt and airbag configuration
- battery_type (str): Battery chemistry (NMC, LFP, etc.)
- drive_unit (str): Motor configuration (Single/Dual/Tri Motor)
- year (str): Model year
- plant_code (str): Manufacturing plant location
"""Methods for decoding Tesla vehicle option codes into human-readable descriptions.
@classmethod
def decode_option(cls, code):
"""
Return option code description or None if unknown.
Parameters:
- code (str): Tesla option code to decode
Returns:
str or None: Human-readable description of the option code, or None if code is unknown
Note:
Option codes appear to be deprecated by Tesla and may not be available
for newer vehicles.
"""
def option_code_list(self):
"""
Return a list of known vehicle option code descriptions.
Returns:
list[str]: List of human-readable descriptions for all option codes
associated with this vehicle
Note:
Filters out None values for unknown option codes.
"""Methods for converting between different unit systems based on vehicle GUI settings.
def dist_units(self, miles, speed=False):
"""
Format and convert distance or speed to vehicle's GUI setting units.
Parameters:
- miles (float or None): Distance in miles or speed in mph
- speed (bool): Whether this is a speed measurement (default: False)
Returns:
str or None: Formatted distance/speed with appropriate units based on
vehicle's gui_distance_units setting, or None if input is None
Examples:
- If GUI set to km: "160.9 km" or "80.5 km/h"
- If GUI set to mi: "100.0 mi" or "50.0 mph"
"""
def temp_units(self, celcius):
"""
Format and convert temperature to vehicle's GUI setting units.
Parameters:
- celcius (float or None): Temperature in Celsius
Returns:
str or None: Formatted temperature with appropriate units based on
vehicle's gui_temperature_units setting, or None if input is None
Examples:
- If GUI set to C: "22.0 C"
- If GUI set to F: "71.6 F"
"""Time formatting utilities that respect vehicle GUI preferences for time display.
def gui_time(self, timestamp_ms=0):
"""
Return timestamp or current time formatted according to vehicle's GUI setting.
Parameters:
- timestamp_ms (int): Timestamp in milliseconds since epoch (default: 0 for current time)
Returns:
str: Formatted time string based on vehicle's gui_24_hour_time setting
Examples:
- If 24-hour time: "14:30:15"
- If 12-hour time: "02:30:15 PM"
"""
def last_seen(self):
"""
Return human-readable time since vehicle was last seen.
Returns:
str: Natural language description of time elapsed since last contact
Examples:
- "just now"
- "5 minutes ago"
- "2 hours ago"
- "3 days ago"
Note:
Uses charge_state timestamp to determine last contact time.
"""Utility class for configuring robust connection retry strategies.
class Retry:
"""
Retry configuration class from urllib3 for handling connection failures.
Used with Tesla constructor to configure automatic retry behavior
for API requests when network issues occur.
"""All standard HTTP and OAuth exceptions are available through the teslapy module for comprehensive error handling.
# From requests.exceptions
HTTPError: HTTP error responses (4xx, 5xx status codes)
ConnectionError: Network connection problems
Timeout: Request timeout errors
RequestException: Base exception for all requests errors
# From oauthlib.oauth2.rfc6749.errors
OAuth2Error: OAuth 2.0 related errors
InvalidClientError: Invalid client credentials
InvalidGrantError: Invalid authorization grant
InvalidRequestError: Malformed requestimport teslapy
with teslapy.Tesla('elon@tesla.com') as tesla:
vehicles = tesla.vehicle_list()
vehicle = vehicles[0]
# Get vehicle data for utilities
vehicle.get_vehicle_data()
# Convert distances based on GUI settings
range_miles = vehicle['charge_state']['battery_range']
print(f"Range: {vehicle.dist_units(range_miles)}")
# Convert speed
if vehicle['drive_state']['speed']:
speed_mph = vehicle['drive_state']['speed']
print(f"Speed: {vehicle.dist_units(speed_mph, speed=True)}")
# Convert temperature
outside_temp = vehicle['climate_state']['outside_temp']
print(f"Outside temperature: {vehicle.temp_units(outside_temp)}")# Decode vehicle identification number
vin_info = vehicle.decode_vin()
print(f"Make: {vin_info['make']}")
print(f"Year: {vin_info['year']}")
print(f"Battery: {vin_info['battery_type']}")
print(f"Drive: {vin_info['drive_unit']}")
print(f"Plant: {vin_info['plant_code']}")
# Full VIN information
print("Complete VIN decode:")
print(vin_info) # JsonDict pretty-prints as JSON# Get option code descriptions (if available)
option_descriptions = vehicle.option_code_list()
if option_descriptions:
print("Vehicle options:")
for option in option_descriptions:
print(f" - {option}")
else:
print("No option code descriptions available")
# Decode individual option code
code_description = teslapy.Vehicle.decode_option('MDLS')
if code_description:
print(f"MDLS means: {code_description}")# Format current time according to vehicle settings
current_time = vehicle.gui_time()
print(f"Current time: {current_time}")
# Format specific timestamp
timestamp_ms = vehicle['charge_state']['timestamp']
formatted_time = vehicle.gui_time(timestamp_ms)
print(f"Last charge update: {formatted_time}")
# Natural language last seen
print(f"Vehicle last seen: {vehicle.last_seen()}")import teslapy
try:
with teslapy.Tesla('elon@tesla.com') as tesla:
vehicles = tesla.vehicle_list()
vehicle = vehicles[0]
# This might raise VehicleError if command fails
vehicle.command('HONK_HORN')
except teslapy.VehicleError as e:
print(f"Vehicle command failed: {e}")
# Handle vehicle-specific errors (command failed, user not present, etc.)
except teslapy.HTTPError as e:
print(f"HTTP error: {e}")
# Handle API errors (408 vehicle unavailable, 401 unauthorized, etc.)
if "408" in str(e):
print("Vehicle is asleep or offline")
elif "401" in str(e):
print("Authentication required")
except teslapy.ConnectionError as e:
print(f"Network connection error: {e}")
# Handle network connectivity issues
except teslapy.Timeout as e:
print(f"Request timed out: {e}")
# Handle timeout scenarios# JsonDict automatically formats as pretty JSON
vehicle_data = vehicle.get_vehicle_data()
print("Vehicle data:")
print(vehicle_data) # Outputs formatted JSON with indentation
# Manual JsonDict creation
custom_data = teslapy.JsonDict({
'battery_level': 85,
'range': 250,
'location': {'lat': 37.7749, 'lng': -122.4194}
})
print(custom_data) # Pretty-printed JSON outputimport teslapy
# Configure retry strategy for unreliable connections
retry = teslapy.Retry(
total=3, # Total number of retries
status_forcelist=(500, 502, 503, 504), # HTTP status codes to retry
backoff_factor=0.3 # Backoff between retries
)
with teslapy.Tesla('elon@tesla.com', retry=retry, timeout=30) as tesla:
try:
vehicles = tesla.vehicle_list()
# Operations will automatically retry on specified failures
except teslapy.HTTPError as e:
print(f"Failed after retries: {e}")def process_vehicle_data(vehicle):
"""Example data processing function using utilities."""
# Ensure we have fresh data
vehicle.get_vehicle_data()
# Extract and convert key metrics
battery_level = vehicle['charge_state']['battery_level']
range_remaining = vehicle.dist_units(vehicle['charge_state']['battery_range'])
outside_temp = vehicle.temp_units(vehicle['climate_state']['outside_temp'])
last_update = vehicle.gui_time(vehicle['charge_state']['timestamp'])
# Get vehicle info
vin_info = vehicle.decode_vin()
# Create summary
summary = teslapy.JsonDict({
'vehicle_name': vehicle['display_name'],
'model': vin_info['make'],
'year': vin_info['year'],
'battery_level': f"{battery_level}%",
'range': range_remaining,
'temperature': outside_temp,
'last_seen': vehicle.last_seen(),
'last_update': last_update,
'location': {
'latitude': vehicle['drive_state']['latitude'],
'longitude': vehicle['drive_state']['longitude']
}
})
return summary
# Process all vehicles
with teslapy.Tesla('elon@tesla.com') as tesla:
vehicles = tesla.vehicle_list()
for vehicle in vehicles:
try:
summary = process_vehicle_data(vehicle)
print(f"\n{summary['vehicle_name']} Summary:")
print(summary)
except teslapy.VehicleError as e:
print(f"Could not process {vehicle['display_name']}: {e}")# Energy product utilities work similarly
with teslapy.Tesla('elon@tesla.com') as tesla:
batteries = tesla.battery_list()
solar_panels = tesla.solar_list()
for battery in batteries:
try:
battery.get_site_data()
# Create summary using JsonDict
battery_summary = teslapy.JsonDict({
'site_name': battery['site_name'],
'battery_level': f"{battery['percentage_charged']}%",
'power': f"{battery['battery_power']} W",
'grid_status': battery['grid_status'],
'operation': battery['operation']
})
print("Battery Status:")
print(battery_summary)
except teslapy.ProductError as e:
print(f"Battery error: {e}")
for solar in solar_panels:
try:
solar.get_site_data()
# Solar summary
solar_summary = teslapy.JsonDict({
'solar_power': f"{solar['solar_power']} W",
'grid_power': f"{solar['grid_power']} W",
'grid_status': solar['grid_status']
})
print("Solar Status:")
print(solar_summary)
except teslapy.ProductError as e:
print(f"Solar error: {e}")Install with Tessl CLI
npx tessl i tessl/pypi-teslapy