My Powerwall arrived last week, so I am now facing this problem space… has anyone actually looked at updating emonhub to speak the new API? @bwduncan @TrystanLea could I use a lib like GitHub - jrester/tesla_powerwall: Python API for Tesla Powerwall or is emonhub supposed to avoid dependencies for $reasons…?
Hey,
Congratulations on your new arrival!
I haven’t looked at this, since I don’t have the hardware. I’d be happy to help, though.
emonhub certainly has dependencies, but the way they are managed is… less than optimal. There is no package management so you just have to try your import at runtime and log a message if it’s not available. Then add documentation so that users know to install it with pip or whatever.
Bruce
Sorry for necroposting, does johnbanks excellent script still work for uploading Tesla Powerwall data (including solar production) into emoncms?
@homeontherocks
The script is still running for me.
It stopped a while ago so I just had to restart the powerall.service
Awesome. Thanks for the reply. I assume you run the script on the emonPi or emonBase unit to automatically upload to emoncms? Also, I have PV and power walls. Does your script upload powerwall battery state (charge and discharge) as well as PV production and flow from PV to battery, house, and/or grid?
Edit: Also, does your script upload to the local instance (self hosted) or the emoncms public website?
Hi John,
Sorry to be so bothersome. I’ve got the 4 data points loading to my local emonPi. Charge_percent and Power_Now are logical but I’m having trouble properly labeling and parsing Total_Export_Energy and Total_Import_Energy. The reported numbers are very large (10 and 12 million, respectively). I’m also curious about the data set. Previously, I have used pvoutput integration to get this data, and it extracts more data points (battery flow, home load, grid flow, battery state, solar generation). Is there a way to pull pull these data points with your script as well? Thanks!
@homeontherocks
In reply to yr 3 posts –
My Powerall script runs on a Raspberry Pi running emoncms software.
It does not capture PV, Grid, Pool ASHP or Electric Vehicle data. I use other methods to bring this data together in emoncms. These are unique to the site - eg: solar panels in a field 100+ metres from the house. It’s all locally hosted - do not use the emoncms website.
Pls see the comments in the script which should make things clear. You need to use the user email address for yr Tesla account and the 5 character password from the Gateway unit.
Lastly re PowerWall import & export energy - these will be a large numbers as they are Wh not kWh. Mine are well over 20 million with 3 PowerWalls.
Nothing like replying to old posts…
I just made a version of the script from @johnbanks that exports all of the data it collects from the inverter. All of the other instructions apply – you will still have to create feeds in EmonCMS from this data and set the units on those feeds. And while this works for me, I don’t have a way to test with multiple batteries, so I’m not sure just how Tesla will respond with that data.
The main difference between this and the original code is that it loops through the data that comes back from the inverter and creates inputs with names like <source>_<metric>
– giving you things like solar_instant_power
, site_energy_exported
, and battery_instant_average_voltage
. The battery percentage charged comes back in a separate metric, so I have labeled that one battery_charge_percent
just to be consistent with the rest of the names. In my install with a single battery, the “category” names are site
, battery
, load
, and solar
. I would be curious to see what other folks see with multiple batteries and more complex installations.
Thanks to @johnbanks for writing the original script. Without this I would have lost all data inputs from my system when I was upgraded from a SolarEdge inverter and first generation Tesla battery to a Tesla gateway, inverter, and PW2 a few weeks ago.
#!/usr/bin/env python3
# PURPOSE: To input key PowerWall data into emoncms
# BACKGROUND - In Jan/Feb 2021, Tesla added a layer of security (with ver 20.49.0) - many 'things' stopped working incl the previous version of this script
# HOW TO ...
# This script is intended to be run on a Raspberry Pi on the local network with PowerWall
# The script will create an INPUT node to receive the data
# Copy this script file to /home/pi and make it executable with: chmod +x /home/pi/JB.powerwall.py # but using the chosen script name
# Run the script with: /usr/bin/python3 /home/pi/JB.powerwall.py # but using the chosen script name
# In emon create FEEDS using Log to Feed and add UNITS (pencil drop-down) to each
# IMPORTANT NOTE ...
# Data from this script is input to emoncms via an http API.
# The EmonHubEmoncmsHTTPinterfacer is not used/required
# IMPORTANT NOTE ...
# Reserve a LAN IP address in the ROUTER to fix it for the connection to PowerWall
# VERY IMPORTANT NOTE ...
# In order to provide continuous functionality, the script must be run as a service - see HOW TO below
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
import sys, requests, json, time, urllib3, os
from time import sleep
from requests.structures import CaseInsensitiveDict
# User Data
t_email = "xxxxxxx@xxxxxxx" # email address for Tesla account
t_pwd = "XXXXX" # The last 5 digits/characters of the password on the sticker behind the cover of the Gateway 2 unit
# Script Run data
loop_freq = "30.0" # The frequency in secs that the script will grab PowerWall data for INPUT to emon
restart_hrs = "48.0" # Belt & braces assuming Tesla will periodically not recognise the current cookie info - so refresh it every restart_hrs
# Belt & braces because, if at any time, Tesla does not recognise current cookie info (ie: the script loses connection), the script will restart
via the powerwall.service
# Emoncms server configuration
emoncms_apikey = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" # For RPi concerned - use appropriate key
emoncms_server = "http://127.0.0.1"
node = "Power_Wall" # Name of the NODE to be created to receive the INPUT data from PowerWall
gateway = "https://192.168.1.119" # IP address of the Tesla Gateway on local network - IMPORTANT: Reserve a LAN IP address in the ROUTER to FIX
it
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# House-keeping ...
loop_freq = float(loop_freq)
restart_secs = float(restart_hrs)*3600
# Initial Basic login to get the cookie info ...
requests.packages.urllib3.disable_warnings() # To disable SSL certificate warnings
url = gateway+"/api/login/Basic"
headers = CaseInsensitiveDict()
headers["Accept"] = "application/json"
headers["Content-Type"] = "application/json"
data = {"username": "customer", "email": t_email, "password": t_pwd} # ref User Data above ...
a_session = requests.Session() # ref: https://www.kite.com/python/answers/how-to-get-session-cookies-from-a-website-in-python
a_session.post(url, headers=headers, data=json.dumps(data), verify=False)
session_cookies = a_session.cookies
cookies_dictionary = session_cookies.get_dict()
# print("Cookies Dictionary is:")
# print(cookies_dictionary)
# print (" ")
# print ("AuthCookie is:")
# print (cookies_dictionary['AuthCookie'])
ac = cookies_dictionary['AuthCookie']
# print (" ")
# print ("UserRecord is:")
# print (cookies_dictionary['UserRecord'])
ur = cookies_dictionary['UserRecord']
# print ("AuthCookie="+ac+";UserRecord="+ur)
# Repetitive Looping starts here ...
# Intro ...
headers = CaseInsensitiveDict()
headers["Cookie"] = "AuthCookie="+ac+";UserRecord="+ur # A KEY LINE - so Tesla recognises 'legitimacy'
headers["Accept"] = "application/json"
headers["Content-Type"] = "application/json"
# Loop ...
starttime = time.time()
while True:
# First enquiry
reply = requests.get(gateway+"/api/system_status/soe", headers=headers, verify=False) # XXXXXXX soe not sof
# print (reply.status_code)
if reply.status_code!=200:
os.system("sudo systemctl restart powerwall.service") # To cover the situation where Tesla no longer recognises the cookie info - so it will be refreshed
time.sleep(10) # A pre-caution
jsonstr = reply.text.rstrip()
data_p1 = json.loads(jsonstr)
# print(data_p1)
# Second enquiry
reply = requests.get(gateway+"/api/meters/aggregates", headers=headers, verify=False)
jsonstr = reply.text.rstrip()
data_p2 = json.loads(jsonstr)
# print (reply.status_code)
# Extract relevant data from the json's
#data1 = data_p1['percentage']
#data2 = data_p2['battery']['instant_power']
#data3 = data_p2['battery']['energy_exported']
#data4 = data_p2['battery']['energy_imported']
# Send data to emoncms
#dev_data = {di1: data1, di2: data2, di3: data3, di4: data4}
dev_data={"battery_charge_percent": data_p1["percentage"]} # Build dict of all data points in response
for k,v in data_p2.items():
for k2,v2 in v.items():
if "_time" in k2: # Skip timestamps
continue
dev_data[f"{k}_{k2}"] = v2
# print (dev_data) # a progress marker - can be commented out
data = {
'node': node,
'data': json.dumps (dev_data),
'apikey': emoncms_apikey
}
response = requests.post(emoncms_server+"/input/post", data=data)
elapsed = time.time() - starttime
# print (elapsed)
if elapsed > restart_secs:
os.system("sudo systemctl restart powerwall.service") # Belt & braces assuming Tesla will eventually not recognise the current cookie info - so refresh it
time.sleep(10) # A pre-caution
# End of Loop
time.sleep(loop_freq - ((time.time() - starttime) % loop_freq)) # Repeat loop every loop_freq secs
# FINALLY ONCE THE SCRIPT RUNS OK: Create the powerwall.service and enable it so the script runs on boot up as follows:
# Do: CTRL-C to stop the script running in the terminal then - Do: sudo nano /etc/systemd/system/powerwall.service and copy & paste in the following (using the correct script name) ...
"""
[Unit]
Description=PowerWall Status
After=network.target
After=mosquitto.service
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always
RestartSec=1
User=pi
ExecStart=/usr/bin/python3 /home/pi/JB.powerwall.py
[Install]
WantedBy=multi-user.target
"""
# Then save & exit and to ensure the powerwall.service runs on boot up - Do ...
# sudo systemctl start powerwall.service and then sudo systemctl enable powerwall.service
# AS A VERY LAST CHECK - Do: sudo reboot then SSH in again and check the service is active with: sudo systemctl status powerwall.service
# Finally close the SSH terminal. The script/service will continue to run surviving any future reboots
# Unkowns: what happens to the script/service when emoncms is updated as it will not be included in any Export ... so - caveat emptor
So a very quick question - I see my Powerwall system now on version 24.12.3 And gaining access to Powerwall state of charge using approaches above has stopped. Investigating it, but interested to hear if the above scripts still working for folk with this Tesla software version?
Appreciate any feedback!