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
Management functionality for Tesla energy products including Powerwall batteries and solar panel installations with status monitoring, configuration, and control capabilities.
Core functionality shared by all Tesla energy products including site data retrieval and historical data access.
class Product(JsonDict):
def api(self, name, **kwargs):
"""
Endpoint request with site_id path variable.
Parameters:
- name (str): Endpoint name
- **kwargs: Endpoint parameters
Returns:
dict: API response
"""
def get_site_info(self):
"""
Retrieve current site/battery information.
Returns:
Product: Updated Product object
"""
def get_site_data(self):
"""
Retrieve current site/battery live status.
Returns:
Product: Updated Product object
"""
def command(self, name, **kwargs):
"""
Wrapper method for product command response error handling.
Parameters:
- name (str): Command name
- **kwargs: Command parameters
Returns:
str: Success message
Raises:
ProductError: If command fails
"""Methods for retrieving historical energy data with various time periods and data types.
def get_history_data(self, kind='energy', period='day', start_date=None,
end_date=None, installation_timezone=None, timezone=None):
"""
Retrieve historical status data for the energy product.
Parameters:
- kind (str): Telemetry type - 'backup', 'energy', 'power', 'self_consumption',
'time_of_use_energy', 'time_of_use_self_consumption' (default: 'energy')
- period (str): Time period - 'day', 'month', 'year', 'lifetime' (default: 'day')
- start_date (str): Start date in JSON format 'YYYY-MM-DDTHH:MM:SS.sssZ' (optional)
- end_date (str): End date in JSON format 'YYYY-MM-DDTHH:MM:SS.sssZ' (optional)
- installation_timezone (str): Timezone of installation location (optional)
- timezone (str): Timezone in JSON format e.g. 'Europe/Brussels' (optional)
Returns:
dict: Historical data response
"""
def get_calendar_history_data(self, kind='energy', period='day', start_date=None,
end_date=None, installation_timezone=None,
timezone=None, tariff=None):
"""
Retrieve calendar-based historical status data for the energy product.
Parameters:
- kind (str): Telemetry type - 'backup', 'energy', 'power', 'self_consumption',
'time_of_use_energy', 'time_of_use_self_consumption', 'savings', 'soe' (default: 'energy')
- period (str): Time period - 'day', 'month', 'year', 'lifetime' (default: 'day')
- start_date (str): Start date in JSON format 'YYYY-MM-DDTHH:MM:SS.sssZ' (optional)
- end_date (str): End date in JSON format 'YYYY-MM-DDTHH:MM:SS.sssZ' (optional)
- installation_timezone (str): Timezone of installation location for 'savings' (optional)
- timezone (str): Timezone in JSON format e.g. 'Europe/Brussels' (optional)
- tariff: Tariff format for 'savings' data type (optional)
Returns:
dict: Calendar historical data response
"""Comprehensive Powerwall battery control including operation modes, backup settings, grid import/export configuration, and time-of-use tariff management.
class Battery(Product):
def set_operation(self, mode):
"""
Set battery operation mode.
Parameters:
- mode (str): Operation mode - 'self_consumption', 'backup', or 'autonomous'
Returns:
str: Success message
"""
def set_backup_reserve_percent(self, percent):
"""
Set the minimum backup reserve percent for the battery.
Parameters:
- percent (int): Backup reserve percentage (0-100)
Returns:
str: Success message
"""
def set_import_export(self, allow_grid_charging=None, allow_battery_export=None):
"""
Set the battery grid import and export settings.
Parameters:
- allow_grid_charging (bool): Whether charging from the grid is allowed (optional)
- allow_battery_export (bool): Whether export to the grid is allowed (optional)
Note:
This endpoint returns an empty response instead of a result code.
"""Powerwall time-of-use tariff configuration for optimizing energy costs and grid interaction.
def get_tariff(self):
"""
Get the current tariff rate data.
Returns:
dict: Tariff configuration data
"""
def set_tariff(self, tariff_data):
"""
Set the tariff rate data.
Parameters:
- tariff_data (dict): Tariff configuration data (can be created with create_tariff)
Returns:
str: Success message
"""
@staticmethod
def create_tariff(default_price, periods, provider, plan):
"""
Create a correctly formatted dictionary of tariff data.
Parameters:
- default_price (BatteryTariffPeriodCost): Price of the background time period
- periods (list[BatteryTariffPeriod]): List of time periods with higher prices
- provider (str): Name of the energy provider
- plan (str): Name of the energy plan
Returns:
JsonDict or None: Formatted tariff data dictionary, or None if periods overlap incorrectly
"""Solar panel installation monitoring and data retrieval functionality.
class SolarPanel(Product):
"""
Solar panel class - inherits all methods from Product base class.
Provides access to solar panel installations with get_site_data() for current
generation data and get_history_data() for historical solar production data.
"""Specialized data types for managing Powerwall time-of-use tariff configurations.
class BatteryTariffPeriodCost:
"""
Represents the costs of a tariff period.
Attributes:
- buy (float): Import price per kWh
- sell (float): Export price per kWh
- name (str): Period name - 'ON_PEAK', 'PARTIAL_PEAK', 'OFF_PEAK', or 'SUPER_OFF_PEAK'
"""
class BatteryTariffPeriod:
"""
Represents a time period of a tariff.
Attributes:
- cost (BatteryTariffPeriodCost): Cost object for this time period
- start (datetime.time): Start time of the period
- end (datetime.time): End time of the period
"""import teslapy
with teslapy.Tesla('elon@tesla.com') as tesla:
batteries = tesla.battery_list()
if batteries:
battery = batteries[0]
# Get current battery status
battery.get_site_data()
print(f"Battery level: {battery['percentage_charged']}%")
print(f"Power: {battery['battery_power']} W")
print(f"Grid status: {battery['grid_status']}")
# Set operation mode to self-consumption
battery.set_operation('self_consumption')
# Set backup reserve to 20%
battery.set_backup_reserve_percent(20)# Allow grid charging but disable battery export
battery.set_import_export(allow_grid_charging=True, allow_battery_export=False)
# Disable grid charging, allow battery export
battery.set_import_export(allow_grid_charging=False, allow_battery_export=True)
# Allow both grid charging and battery export
battery.set_import_export(allow_grid_charging=True, allow_battery_export=True)import teslapy
import datetime
# Create tariff period costs
off_peak_cost = teslapy.BatteryTariffPeriodCost(buy=0.10, sell=0.05, name='OFF_PEAK')
on_peak_cost = teslapy.BatteryTariffPeriodCost(buy=0.25, sell=0.15, name='ON_PEAK')
# Define time periods
morning_peak = teslapy.BatteryTariffPeriod(
cost=on_peak_cost,
start=datetime.time(hour=7),
end=datetime.time(hour=10)
)
evening_peak = teslapy.BatteryTariffPeriod(
cost=on_peak_cost,
start=datetime.time(hour=17),
end=datetime.time(hour=21)
)
# Create and set tariff
tariff_data = teslapy.Battery.create_tariff(
default_price=off_peak_cost,
periods=[morning_peak, evening_peak],
provider="Local Utility",
plan="Time of Use"
)
if tariff_data:
battery.set_tariff(tariff_data)
print("Tariff configured successfully")
else:
print("Failed to create tariff - check time period overlaps")import time
# Get today's energy data
today = time.strftime('%Y-%m-%dT%H:%M:%S.000Z')
yesterday = time.strftime('%Y-%m-%dT%H:%M:%S.000Z',
time.gmtime(time.time() - 86400))
# Get daily energy history
energy_data = battery.get_history_data(
kind='energy',
period='day',
start_date=yesterday,
end_date=today,
timezone='America/Los_Angeles'
)
print(f"Energy consumption: {energy_data}")
# Get power data with calendar history
power_data = battery.get_calendar_history_data(
kind='power',
period='day',
timezone='America/Los_Angeles'
)
print(f"Power usage: {power_data}")with teslapy.Tesla('elon@tesla.com') as tesla:
solar_panels = tesla.solar_list()
if solar_panels:
solar = solar_panels[0]
# Get current solar generation
solar.get_site_data()
print(f"Current solar power: {solar['solar_power']} W")
print(f"Grid power: {solar['grid_power']} W")
# Get solar energy history
solar_history = solar.get_history_data(
kind='energy',
period='month',
timezone='America/Los_Angeles'
)
print(f"Monthly solar generation: {solar_history}")with teslapy.Tesla('elon@tesla.com') as tesla:
batteries = tesla.battery_list()
solar_panels = tesla.solar_list()
if batteries and solar_panels:
battery = batteries[0]
solar = solar_panels[0]
# Get current status of both systems
battery.get_site_data()
solar.get_site_data()
# Calculate net energy flow
battery_power = battery['battery_power']
solar_power = solar['solar_power']
grid_power = battery.get('grid_power', 0)
print(f"Solar generation: {solar_power} W")
print(f"Battery power: {battery_power} W")
print(f"Grid power: {grid_power} W")
if grid_power < 0:
print(f"Exporting {abs(grid_power)} W to grid")
elif grid_power > 0:
print(f"Importing {grid_power} W from grid")
else:
print("No grid interaction")try:
battery.set_operation('invalid_mode')
except teslapy.ProductError as e:
print(f"Product command failed: {e}")
except teslapy.HTTPError as e:
print(f"API error: {e}")
# Check if battery is available before commands
try:
battery.get_site_info()
battery.set_backup_reserve_percent(25)
except teslapy.HTTPError as e:
if "offline" in str(e).lower():
print("Battery system is offline")
else:
print(f"Unexpected error: {e}")# Configure multiple batteries
with teslapy.Tesla('elon@tesla.com') as tesla:
batteries = tesla.battery_list()
for i, battery in enumerate(batteries):
print(f"Configuring battery {i+1}...")
# Set consistent operation mode
battery.set_operation('self_consumption')
# Set backup reserve based on battery index
reserve_percent = 20 + (i * 5) # 20%, 25%, 30%, etc.
battery.set_backup_reserve_percent(reserve_percent)
# Get current status
battery.get_site_data()
print(f"Battery {i+1}: {battery['percentage_charged']}% charged, "
f"{reserve_percent}% reserve")Install with Tessl CLI
npx tessl i tessl/pypi-teslapy