One cool thing about buying both the Tesla Energy Gateway and Model 3 is that the Tesla app shows the status of both the solar and the car. Since the app has public APIs, they’ve been reverse-engineered. Using that, I wrote a quick script which checks how the solar is performing, and only tells the car to charge if there’s enough juice stored in the battery.
I did have to set the speed the car would charge down about as low as it could go, because the car has a battery that is so much bigger than the PowerWall. If you maxed it out the car it would easily suck the battery and the solar dry, kind of defeating the purpose of free energy.
import asyncio
from tesla_api import TeslaApiClient
import datetime
import time
import os
async def main ():
username = os . environ [ 'USERNAME' ]
password = os . environ [ 'PASSWORD' ]
client = TeslaApiClient ( username , password )
vehicles = await client . list_vehicles ()
v = vehicles [ 0 ]
await v . wake_up ()
await v . get_state ()
energy_sites = await client . list_energy_sites ()
e = energy_sites [ 0 ]
charging_state = await v . charge . get_state ()
state = charging_state [ "charging_state" ]
try :
while True :
status = await e . get_energy_site_live_status ()
print ( datetime . datetime . now (), "House:" , status [ 'load_power' ], "Solar:" , status [ 'solar_power' ],
"Percent:" , f " { status [ 'percentage_charged' ] : .2f } " , "Car Charge:" , state )
if status [ 'percentage_charged' ] > 75 :
if state != "Charging" and status [ 'load_power' ] + 1000 < status [ 'solar_power' ]:
desired_state = "Charging"
elif state == "Charging" and status [ 'load_power' ] <= status [ 'solar_power' ]:
desired_state = "Charging"
else :
desired_state = "Stopped"
else :
desired_state = "Stopped"
if state != desired_state :
if desired_state == "Charging" :
print ( "Starting charge" )
await v . charge . start_charging ()
elif desired_state == "Stopped" :
print ( "Stopping charge" )
await v . charge . stop_charging ()
state = desired_state
time . sleep ( 300 )
finally :
await client . close ()
asyncio . run ( main ())
There’s obviously a lot that could be done here with more efficient state management and error handling, but this is already pretty useful.
Powered by Pelican . Theme blueidea , inspired by the default theme.