Integration Service not working for Powerwall SW Ver. 20.49.0

Usually means the token is invalid, there shouldn’t be any < > in the token

"Authorization: Bearer OgiGHjoNvwx17SRIaYFIOWPJSaKBYwmMGc5K4tTz57EziltPYsdtjU_DJ08tJqaWbWjTuI3fa_8QW32ED5zg1A=="

Bit of topic, but hope this helps - makeshift py script just to keep things updated until problem is solved. Using python implementation of the Powerwall API https://github.com/jrester/tesla_powerwall and parts from @ekul_135 's Powerwall2PVOutput
Works with the firmware 20.49.0
! Please verify the mapping of extended parameters to your PVOutput system

from tesla_powerwall import Powerwall
from tesla_powerwall import MeterType
from tesla_powerwall import API
import os
import datetime
import time
import urllib
import http.client
import ssl
import sys
import logging
from logging.handlers import RotatingFileHandler
from logging import handlers

log_file = "pw2pvo.log"
pvo_host= "pvoutput.org"
pvo_key = "<your PVOutput System key>"
pvo_sysid = "<your PVOutput System ID>"
pwemail = "<Your Powerwall Customer Email>"
pwpass = "<Your Powerwall Customer Password>"
powerwall = Powerwall("<Your Powerwall IP>")

log = logging.getLogger('')
log.setLevel(logging.INFO)
format = logging.Formatter("%(asctime)s - %(message)s")
ch = logging.StreamHandler(sys.stdout)
ch.setFormatter(format)
log.addHandler(ch)
fh = handlers.RotatingFileHandler(log_file, maxBytes=(1048576*5), backupCount=1)
fh.setFormatter(format)
log.addHandler(fh)
logger = logging.getLogger(__name__)
logger.info('Start Test')

if (not os.environ.get('PYTHONHTTPSVERIFY', '') and getattr(ssl, '_create_unverified_context', None)):
    ssl._create_default_https_context = ssl._create_unverified_context

class Connection():
    def __init__(self, api_key, system_id, host):
        self.host = host
        self.api_key = api_key
        self.system_id = system_id

    def get_status(self, date=None, time=None):
        path = '/service/r2/getstatus.jsp'
        params = {}
        if date:
            params['d'] = date
        if time:
            params['t'] = time
        params = urllib.urlencode(params)
        response = self.make_request("GET", path, params)
        if response.status == 400:
            # Initialise a "No status found"
            return "%s,00:00,,,,,,," % datetime.datetime.now().strftime('%Y%m%d')
        if response.status != 200:
            raise StandardError(response.read())
        return response.read()

    def add_status(self, date, time, energy_exp=None, power_exp=None, energy_imp=None, power_imp=None, temp=None, voltage=None, battery=None, home=None, soc=None, gird=None, frequency=None, solar=None, cumulative=False):
        path = '/service/r2/addstatus.jsp'
        params = {
                'd': date,
                't': time
                }
        if energy_exp:
            params['v1'] = energy_exp
        if power_exp:
            params['v2'] = power_exp
        if energy_imp:
            params['v3'] = energy_imp
        if power_imp:
            params['v4'] = power_imp
        if temp:
            params['v5'] = temp
        if voltage:
            params['v6'] = voltage
        if battery:
            params['v7'] = battery
        if home:
            params['v8'] = home
        if soc:
            params['v11'] = soc    
        if gird:
            params['v10'] = gird
        if frequency:
            params['v9'] = frequency
        if solar:
            params['v12'] = solar    
        if cumulative:
            params['c1'] = 1
        params = urllib.parse.urlencode(params)
        response = self.make_request('POST', path, params)
        if response.status == 400:
            raise ValueError(response.read())
        if response.status != 200:
            raise StandardError(response.read())
    
    def make_request(self, method, path, params=None):
        conn = http.client.HTTPConnection(self.host)
        headers = {
                'Content-type': 'application/x-www-form-urlencoded',
                'Accept': 'text/plain',
                'X-Pvoutput-Apikey': self.api_key,
                'X-Pvoutput-SystemId': self.system_id
                }
        conn.request(method, path, params, headers)
        return conn.getresponse()


# Identify the powerwall version
powerwall.detect_and_pin_version()
print("Detected and pinned version: {}".format(powerwall.get_pinned_version()))
if powerwall.is_authenticated():
    logger.info("Logged in")
else:
    powerwall.login(pwemail, pwpass)
logger.info("Authenticated to Powerwall")

api=powerwall.get_api()

while True:
    try:
        aGirdPower=[]
        aHomePower=[]
        aHomeVoltage=[]
        aHomeFrequency=[]
        aSolarPower=[]
        aBatteryPower=[]
        aBatteryCharge=[]
        i=0
        while i<60:      
            soe=api.get_system_status_soe()
            pwm=api.get_meters_aggregates()
            aGirdPower.append(pwm['site']['instant_power'])
            aHomePower.append(pwm['load']['instant_power'])
            aHomeVoltage.append(pwm['load']['instant_average_voltage'])
            aHomeFrequency.append(pwm['load']['frequency'])
            aSolarPower.append(pwm['solar']['instant_power'])
            aBatteryPower.append(pwm['battery']['instant_power'])
            aBatteryCharge.append(soe['percentage'])
            i=i+1
            time.sleep(5)
        if len(aHomePower)>0:
            GirdPower=sum(aGirdPower,0.00)/len(aGirdPower)
            HomePower=sum(aHomePower,0.00)/len(aHomePower)
            HomeVoltage=sum(aHomeVoltage,0.00)/len(aHomeVoltage)
            HomeFrequency=sum(aHomeFrequency,0.00)/len(aHomeFrequency)
            SolarPower=sum(aSolarPower,0.00)/len(aSolarPower)
            BatteryPower=sum(aBatteryPower,0.00)/len(aBatteryPower)
            BatteryCharge=sum(aBatteryCharge,0.00)/len(aBatteryCharge)
            print(HomePower,HomeVoltage,HomeFrequency)
            print(SolarPower)
            print(GirdPower)
            print(BatteryPower,BatteryCharge)
            if SolarPower<0 :
                HomePower=HomePower-SolarPower
                SolarPower=0
            sdate=datetime.datetime.now()
            pvoDate=sdate.strftime("%Y%m%d")
            pvoTime=sdate.strftime("%H:%M")
            logger.info(str(pvoDate)+","+str(pvoTime)+","+str(SolarPower)+","+str(HomePower)+","+str(HomeVoltage)+","+str(BatteryPower)+","+str(HomePower)+","+str(BatteryCharge)+","+str(GirdPower)+","+str(HomeFrequency)+","+str(SolarPower))
            pvocon=Connection(pvo_key, pvo_sysid, pvo_host)
            pvocon.add_status(pvoDate, pvoTime, power_exp=SolarPower, power_imp=HomePower, voltage=HomeVoltage, battery=BatteryPower, home=HomePower, soc=BatteryCharge, gird=GirdPower, frequency=HomeFrequency, solar=SolarPower)
        else:
            print(str(pvoDate)+","+str(pvoTime)+", Error: No data to sent")
            logger.info(str(pvoDate)+","+str(pvoTime)+", Error: No data to sent")
    except StandardError as e:
        logger.info(str(e))
        time.sleep(30)
1 Like

no, i didn’t put any carets or anything… it just didn’t work. my syntax is exactly as you have quoted. i even logged in once more and got a new token and then immediately tried it.

1 Like

thanks, as it turns out i was using PowerWall2PVOutput and started looking into how to have it handle the login and cookie and pretty quickly realized that it was based on some pretty old stuff (urllib instead of request) and will take more python knowledge than i have to fix. i’ll give your code a try.

Try sending back just the AuthCookie returned from gateway login, no token.

curl -k --cookies "AuthCookie=<cookie_data>" https://192.168.xxx.xxx/api/meters/aggregates

Please test the following patch which will now login to the gateway -

  1. Stop the service
  2. Make a backup of file <pvoutput_install>\lib\org.pvoutput.integration.jar
  3. Download the patch -
  4. Rename from org.pvoutput.integration_1.5.5.1.jar to org.pvoutput.integration.jar
  5. Copy org.pvoutput.integration.jar to the PVOutput installation lib folder, replacing the existing file.
  6. Edit conf\powerwall.ini and add lines with gateway ip
    • login-url=https://192.168.x.x/api/login/Basic
    • login-pass=your_password
  7. Start the service

If the above works v1.5.5.1 will be released.

2 Likes

sorry - i had gone to bed (PST) but i did try this just now and i got data back from the powerwall. so passing the auth cookie does work.

i’ll try the java program but it might take me a little while as i’ve been using the python scripts up to this point.

@bankstownbloke - it works, thank you!


 2021-02-10 09:13:09,382  INFO [Thread-2] (WebClient.java:226) - >>> https://192.168.0.136/api/login/Basic
2021-02-10 09:13:09,397  INFO [Thread-1] (Controller.java:435) - Found 1 Sensors
2021-02-10 09:13:09,397  INFO [Thread-1] (Controller.java:536) - Added Reader: powerwall0
2021-02-10 09:13:09,397  INFO [Thread-1] (ADataLogReader.java:350) - Output stop at 1080 minutes
2021-02-10 09:13:09,397  INFO [Thread-1] (Controller.java:560) - Log File: powerwall0 [PW0-2021-02-10.log]
2021-02-10 09:13:09,397  INFO [Thread-1] (Controller.java:572) - Export Sensor: 0, id: 0
2021-02-10 09:13:09,413  INFO [Thread-1] (Controller.java:579) - Service: [http://pvoutput.org:80/service/r2/addbatchstatus.jsp] Test: false, End: 18:00
2021-02-10 09:13:09,413  INFO [Thread-1] (Controller.java:587) - Loaded 1 Readers (Import: 0, Export: 1)
2021-02-10 09:13:10,647  INFO [Thread-1] (Controller.java:1524) - Records restored from status.log : 25932
2021-02-10 09:13:11,709  INFO [Thread-2] (PowerwallLogReader.java:72) - Successful gateway authentication
2021-02-10 09:13:11,709  INFO [Thread-2] (WebClient.java:356) - >>> https://192.168.0.136:443/api/meters/aggregates
2021-02-10 09:13:11,834  INFO [Thread-2] (WebClient.java:157) - >>> https://192.168.0.136/api/system_status/soe
2021-02-10 09:13:12,647  INFO [Thread-1] (Controller.java:731) - Startup Complete: Waiting for data...
2021-02-10 09:13:12,678  INFO [Thread-1] (Controller.java:1806) - >>> 20210210,09:15,-1.0,3536,-1,-1,-1000.0,-1.0,10,483.026,60,-3065.93,99.043,3536.38
2021-02-10 09:13:12,678  INFO [Thread-1] (WebClient.java:135) - >>> http://pvoutput.org:80/service/r2/addbatchstatus.jsp?data=20210210,09:15,-1.0,3536,-1,-1,-1000.0,-1.0,10,483.026,60,-3065.93,99.043,3536.38
2021-02-10 09:13:12,804  INFO [Thread-1] (Controller.java:1834) - <<< 20210210,09:15,1
2 Likes

Thanks for confirming this.

PVOutput Integration Service v1.5.5.1 released with the Powerwall authentication requirement for firmware version 20.49.0

5 Likes

I have just reinstalled using your updated PVOutput Integration Service v1.5.5.1 and everything is up and running again - many thanks for addressing this issue so promptly.

1 Like

Good work as always!
I installed everything from scratch using the PVOutput_Integration_Service_v1.5.5.1_Setup
and eventually got everything to work. However, it seems like the wrapper is a 32bit version while I only have JVM 64bit installed.
What do you recommend ?
Here is the error:
STATUS | wrapper | 2021/02/17 20:55:07 | --> Wrapper Started as Service
STATUS | wrapper | 2021/02/17 20:55:07 | Java Service Wrapper Community Edition 32-bit 3.5.4
STATUS | wrapper | 2021/02/17 20:55:07 | Copyright © 1999-2010 Tanuki Software, Ltd. All Rights Reserved.
STATUS | wrapper | 2021/02/17 20:55:07 | http://wrapper.tanukisoftware.com
STATUS | wrapper | 2021/02/17 20:55:07 |
STATUS | wrapper | 2021/02/17 20:55:08 | Launching a JVM…
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: Initializing…
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager:
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: WARNING - Unable to load the Wrapper’s native library ‘wrapper.dll’.
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: The file is located on the path at the following location but
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: could not be loaded:
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: C:\Program Files (x86)\PVOutput\bin…\lib\wrapper.dll
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: Please verify that the file is both readable and executable by the
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: current user and that the file has not been corrupted in any way.
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: One common cause of this problem is running a 32-bit version
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: of the Wrapper with a 64-bit version of Java, or vica versa.
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: This is a 64-bit JVM.
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: Reported cause:
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: C:\Program Files (x86)\PVOutput\lib\wrapper.dll: Can’t load IA 32-bit .dll on a AMD 64-bit platform
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager: System signals will not be handled correctly.
INFO | jvm 1 | 2021/02/17 20:55:08 | WrapperManager:
INFO | jvm 1 | 2021/02/17 20:55:08 | *** Starting PVOutput Integration Service v1.5.5.1
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.runtime.name=Java™ SE Runtime Environment
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vm.version=25.281-b09
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vm.vendor=Oracle Corporation
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vendor.url=http://java.oracle.com/
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vm.name=Java HotSpot™ 64-Bit Server VM
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vm.specification.name=Java Virtual Machine Specification
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.runtime.version=1.8.0_281-b09
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.awt.graphicsenv=sun.awt.Win32GraphicsEnvironment
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.endorsed.dirs=C:\Program Files\Java\jre1.8.0_281\lib\endorsed
INFO | jvm 1 | 2021/02/17 20:55:08 | >> os.arch=amd64
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.io.tmpdir=C:\WINDOWS\system32\config\systemprofile\AppData\Local\Temp
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vm.specification.vendor=Oracle Corporation
INFO | jvm 1 | 2021/02/17 20:55:08 | >> os.name=Windows 10
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.library.path=…/lib
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.specification.name=Java Platform API Specification
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.class.version=52.0
INFO | jvm 1 | 2021/02/17 20:55:08 | >> os.version=10.0
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.awt.printerjob=sun.awt.windows.WPrinterJob
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.specification.version=1.8
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.class.path=…/lib/wrapper.jar;…/lib/org.pvoutput.integration.jar;…/lib/commons-logging-1.1.1.jar;…/lib/httpcore-4.1.2.jar;…/lib/httpclient-4.1.2.jar;…/lib/jetty-http-7.5.1.v20110908.jar;…/lib/jetty-util-7.5.1.v20110908.jar;…/lib/jetty-io-7.5.1.v20110908.jar;…/lib/jetty-server-7.5.1.v20110908.jar;…/lib/jetty-continuation-7.5.1.v20110908.jar;…/lib/servlet-api-2.5.jar;…/lib/json_simple-1.1.jar;…/lib/jxl.jar;…/lib/log4j-1.2.15.jar;…/lib/RXTXcomm.jar;…/lib/jackcess-1.2.2.jar;…/lib/bsh-core-2.0b4.jar;…/lib/sqlitejdbc-v056.jar;…/lib/commons-net-3.1.jar
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vm.specification.version=1.8
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.home=C:\Program Files\Java\jre1.8.0_281
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.specification.vendor=Oracle Corporation
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vm.info=mixed mode
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.version=1.8.0_281
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.ext.dirs=C:\Program Files\Java\jre1.8.0_281\lib\ext;C:\WINDOWS\Sun\Java\lib\ext
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vendor=Oracle Corporation
INFO | jvm 1 | 2021/02/17 20:55:08 | >> java.vendor.url.bug=http://bugreport.sun.com/bugreport/

Could I suggest that this step is included in the “Upgrading.html” file in the update package? For my PW the default password is the last 5 digits of the serial number https://www.tesla.com/en_gb/support/energy/powerwall/own/monitoring-from-home-network .

Thanks for the install note, John.
I have added the lines to conf\powerwall.ini as per image:

however, getting this error:

NFO [Thread-2] (WebClient.java:226) - >>> https://192.168.1.zzz![19-002|602x500] /api/login/basic
2021-02-19 14:21:46,949 WARN [Thread-2] (DefaultRequestDirector.java:1095) - Authentication error: Unable to respond to any of these challenges: {}
2021-02-19 14:21:46,949 ERROR [Thread-2] (WebClient.java:298) - <<< [401] {“code”:401,“error”:“Provider does not exist basic”,“message”:“Login Error”}
2021-02-19 14:21:46,949 WARN [Thread-2] (PowerwallLogReader.java:77) - Failed gateway authentication

Is that first letter of “basic” case-sensitive? I used the capital letter as in the instructions.

You can check if the password OK by doing a manual login to the gateway’s IP address. It now wants an email address and password in order to show the animate power flow display.

1 Like

Brilliant John!
That was exactly it (Basic with a capital B).
All good now Thank you to you, bankstownbloke and rpfile for getting this working again.
Very happy!

Cheers

This is only a warning, the service should start and pvoutput.log will show activity.

1 Like

Indeed it does! In fact it has been like that for years.

Let me ask you another thing. I had to services running one for direction = in and one = out
I remember that was your suggestion at the time.
If I just wanted to update the .jar and the two config files, would that be all that is needed?

Like you explained earlier during testing (See below)
" 1. Stop the service
2. Make a backup of file <pvoutput_install>\lib\org.pvoutput.integration.jar
3. Download the patch -

  1. Rename from org.pvoutput.integration_1.5.5.1.jar to org.pvoutput.integration.jar
  2. Copy org.pvoutput.integration.jar to the PVOutput installation lib folder, replacing the existing file.
  3. Edit conf\powerwall.ini and add lines with gateway ip
  • login-url=https://192.168.x.x/api/login/Basic
  • login-pass=your_password
  1. Start the service"

Yes, the jar should be replaced in both locations.

1 Like

Thanks for the suggestion, [bankstownbloke]. That, and googling around a few other sites, enabled me to get my monitoring back on the air. Here is the Linux script which I found to work:

token=curl -c cookies -s -k -X POST -H "Content-Type: application/json" -d '{"username":"customer","password":"yourteslapassword","force_sm_off":false}' https://teslalan.fritz.box/api/login/Basic | jq -r '.token'

curl -b cookies -s -k --header “AuthCookie=$token” “https://teslalan.fritz.box/api/system_status/soe” | jq -r ‘.percentage’

last month my Gateway 2 was replaced, basically by changing the guts. the sticker was not changed…that means i have no record of the password. Is there some way i can find it inside the box (happy to remove the inner cover)? Resetting the password requires me to know the wifi password to do the reset…and that’s what i don’t have as it is the old sticker!