Skip to content

Commit

Permalink
Add test script for tedapi API
Browse files Browse the repository at this point in the history
  • Loading branch information
jasonacox committed Nov 22, 2023
1 parent b1232d1 commit 3572f0c
Show file tree
Hide file tree
Showing 3 changed files with 102 additions and 4 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -143,3 +143,4 @@ tools/set-reserve.conf
tools/set-mode.auth
tools/set-mode.conf
tools/tedapi/request.bin
tools/tedapi/app*
24 changes: 20 additions & 4 deletions tools/tedapi/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,23 @@

This tool is to help decode `/tedapi` API payloads (requests and responses) using a Protobuf schema definition file [tedapi.proto](tedapi.proto).

## Tool
## Tools

The [test.py](test.py) script will query the user for the Powerwall Gateway password and proceed to fetch the DIN, the configuration of the Powerwall and then the Powerwall status (TODO).

```bash
# Build python bindings for protobuf schema - tedapi_pb2.py
protoc --python_out=. tedapi.proto
# Download
git clone https://github.com/jasonacox/pypowerwall.git
cd pypowerwall/tools/tedapi

# Test Script
python test.py
```

The [decode.py](decode.py) scrip will use the tedapi protobuf schema to decode a specified payload. This is useful for troubleshooting and downloading payloads with curl.

# Decode payload
```bash
# Decode payload file
python decode.py <filename>
```

Expand All @@ -17,6 +27,12 @@ python decode.py <filename>
* This requires using the gateway WiFi access point (for PW2/+ systems this is TEG-xxx and for PW3 it is TeslaPW_xxx) and the https://192.168.91.1 endpoint. It seems that this is required for the /tedapi endpoints (LAN or other access results in "User does not have adequate access rights" 403 Error)
* The /tedapi API calls are using binary Protocol Buffers ([protobuf](https://protobuf.dev/)) payloads.

The protobuf python bindings were created using this:
```bash
# Build python bindings for protobuf schema - tedapi_pb2.py
protoc --python_out=. tedapi.proto
```

## APIs

### GET /tedapi/din
Expand Down
81 changes: 81 additions & 0 deletions tools/tedapi/test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
# -*- coding: utf-8 -*-
"""
Python script to poll /tedapi API for DIN, Config and Status
Requires:
- Protobuf pip install protobuf
- Generate tedapi_pb2.py with protoc --python_out=. tedapi.proto
Author: Jason A. Cox
For more information see https://github.com/jasonacox/pypowerwall
"""

import tedapi_pb2
import requests
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)

# Globals
GW_IP = "192.168.91.1"

# Print Header
print("Tesla Powerwall Gateway API Decoder")
print("")
print("Connect to your Powerwall Gateway WiFi.")

# Get GW_PWD from User
gw_pwd = input("Enter Powerwall Gateway Password: ")

# Fetch DIN from Powerwall
print("Fetching DIN from Powerwall...")
url = f'https://{GW_IP}/tedapi/din'
r = requests.get(url, auth=('Tesla_Energy_Device', gw_pwd), verify=False)
print(f"Response: {r.status_code}")
din = r.text
print(f"Powerwall Gateway DIN: {din}")
print("\n\n")

# Fetch Configuration from Powerwall
print("Fetching Configuration from Powerwall...")
# Build Protobuf to fetch config
pb = tedapi_pb2.ParentMessage()
pb.message.deliveryChannel = 1
pb.message.sender.local = 1
pb.message.recipient.din = din # DIN of Powerwall
pb.message.config.send.num = 1
pb.message.config.send.file = "config.json"
pb.tail.value = 1
url = f'https://{GW_IP}/tedapi/v1'
r = requests.post(url, auth=('Tesla_Energy_Device', gw_pwd), verify=False,
headers={'Content-type': 'application/octet-string'},
data=pb.SerializeToString())
print(f"Response Code: {r.status_code}")
# Decode response
tedapi = tedapi_pb2.ParentMessage()
tedapi.ParseFromString(r.content)
print(f"Data: {tedapi}")
print("\n\n")

# Fetch Current Status from Powerwall
print("Fetching Current Status from Powerwall...")
# Build Protobuf to fetch status
pb = tedapi_pb2.ParentMessage()
pb.message.deliveryChannel = 1
pb.message.sender.local = 1
pb.message.recipient.din = din # DIN of Powerwall
pb.message.payload.send.num = 2
pb.message.payload.send.payload.value = 1
pb.message.payload.send.payload.text = " query DeviceControllerQuery " # TODO
pb.message.payload.send.code = b'0\201\210' # TODO
pb.message.payload.send.b.value = "{}"
pb.tail.value = 1
url = f'https://{GW_IP}/tedapi/v1'
r = requests.post(url, auth=('Tesla_Energy_Device', gw_pwd), verify=False,
headers={'Content-type': 'application/octet-string'},
data=pb.SerializeToString())
print(f"Response Code: {r.status_code}")
# Decode response
tedapi = tedapi_pb2.ParentMessage()
tedapi.ParseFromString(r.content)
print(f"Data: {tedapi}")
print("\n\n")

0 comments on commit 3572f0c

Please sign in to comment.