jasonacox / pypowerwall

Python API for Tesla Powerwall and Solar Power Data
MIT License
134 stars 24 forks source link

Add TeslaGateway Class #73

Closed jasonacox closed 4 months ago

jasonacox commented 7 months ago

This PR adds the TeslaGateway class for access to the device configuration and status payloads available from the local Gateway WiFi access point (192.168.91.1) API (/tedapi).

Requirements:

Example Usage:

from pypowerwall.tedapi import TeslaGateway

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

# Fetch data from Powerwall
gw = TeslaGateway(gw_pwd)
print("Fetching DIN...")
print(gw.get_din())

print("Fetching Configuration...")
print(gw.get_config())

print("Fetching Status...")
print(gw.get_status())
mcbirse commented 6 months ago

Hi Jason - tried testing this without success.... any ideas?

Does it definitely work with the normal gateway password or need installer password/access (which I don't have)?

There could also possibly be a setup issue with my test system. I often seem to have issues with getting the google protobuf module installed and working.

Tesla Powerwall Gateway API Decoder
Connect to your Powerwall Gateway WiFi.
Enter Powerwall Gateway Password: XXXXX
Fetching DIN...
Error fetching DIN: 403
None
Fetching Configuration...
Error fetching DIN: 403
Traceback (most recent call last):
  File "/home/admin/.venv/lib/python3.11/site-packages/google/protobuf/internal/python_message.py", line 696, in field_setter
    new_value = type_checker.CheckValue(new_value)
                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/admin/.venv/lib/python3.11/site-packages/google/protobuf/internal/type_checkers.py", line 184, in CheckValue
    raise TypeError(message)
TypeError: None has type <class 'NoneType'>, but expected one of: (<class 'bytes'>, <class 'str'>)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/home/admin/jasonacox/pypowerwall/tedtest.py", line 15, in <module>
    print(gw.get_config())
          ^^^^^^^^^^^^^^^
  File "/home/admin/jasonacox/pypowerwall/pypowerwall/tedapi.py", line 106, in get_config
    pb.message.recipient.din = self.din  # DIN of Powerwall
    ^^^^^^^^^^^^^^^^^^^^^^^^
  File "/home/admin/.venv/lib/python3.11/site-packages/google/protobuf/internal/python_message.py", line 711, in setter
    field_setter(self, new_value)
  File "/home/admin/.venv/lib/python3.11/site-packages/google/protobuf/internal/python_message.py", line 698, in field_setter
    raise TypeError(
TypeError: Cannot set tedapi.Participant.din to None: None has type <class 'NoneType'>, but expected one of: (<class 'bytes'>, <class 'str'>)
jasonacox commented 6 months ago

@mcbirse Thanks for checking on this. I'll need to rethink how we set this up for 0.8.0.

The password is the one that is on the QR code sticker on the Powerwall that the Installer would use. Do you have that one?

mcbirse commented 6 months ago

The password is the one that is on the QR code sticker on the Powerwall that the Installer would use. Do you have that one?

Ahah - thanks @jasonacox - I should have checked that. I was using the last 5 characters of the password from the sticker, when it needed to be the full password.

It gets my DIN now, but crashes after that. I have not had a chance to check why.

Tesla Powerwall Gateway API Decoder
Connect to your Powerwall Gateway WiFi.
Enter Powerwall Gateway Password: XXXXXXXXXX
Fetching DIN...
XXXXXXX-XX-X--XXXXXXXXXXXXXX
Fetching Configuration...
Traceback (most recent call last):
  File "/home/admin/jasonacox/pypowerwall/tedtest.py", line 15, in <module>
    print(gw.get_config())
          ^^^^^^^^^^^^^^^
  File "/home/admin/jasonacox/pypowerwall/pypowerwall/tedapi.py", line 121, in get_config
    config = json.loads(tedapi.message.config.recv.file)
             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/usr/lib/python3.11/json/__init__.py", line 339, in loads
    raise TypeError(f'the JSON object must be str, bytes or bytearray, '
TypeError: the JSON object must be str, bytes or bytearray, not ConfigString

@mcbirse Thanks for checking on this. I'll need to rethink how we set this up for 0.8.0.

I was hoping that I would be able to get vitals/alerts back for my system (and temps would be good, if they are there somewhere).

If it worked, ideally it would nice to add the tedapi vitals call into pypowerwall proxy for those on the new firmware.

And since I have bridged 192.168.91.1 onto my LAN, then it would be easy to add the "/alerts/pw" (vitals) call to be fetched via the direct IP address, either within the one instance of the proxy (i.e. specify a different IP address to the gateway for vitals/alerts calls), or by running another instance of the proxy just for this (noting I still have the gateway hardwired via ethernet as well and obviously that is best to use for the majority of calls).

jasonacox commented 6 months ago

If it worked, ideally it would nice to add the tedapi vitals call into pypowerwall proxy for those on the new firmware.

That was my thought as well.

It gets my DIN now, but crashes after that. I have not had a chance to check why.

Make sure you have the latest protobuf library. I moved to a different laptop and it wasn't working. It turned out I needed to upgrade protobuf.

Check the command line version too: https://github.com/jasonacox/pypowerwall/tree/main/tools/tedapi

jasonacox commented 4 months ago

Closing this - Moving this class into tedapi