diff --git a/README.md b/README.md index 5ec44ef..414a3c1 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ [![Python Version](https://img.shields.io/pypi/pyversions/pypowerwall)](https://img.shields.io/pypi/pyversions/pypowerwall) [![PyPI Downloads](https://static.pepy.tech/badge/pypowerwall/month)](https://static.pepy.tech/badge/pypowerwall/month) -Python module to interface with Tesla Energy Gateways for Powerwall and solar power data. +Python module to interface with Tesla Energy Gateways for Powerwall and solar power data. Currently supporting Powerwall, Powerwall 2 and Powerwall+ systems. ## Description diff --git a/RELEASE.md b/RELEASE.md index c88cba9..ec006ff 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,5 +1,31 @@ # RELEASE NOTES +## v0.6.3 - Powerwall 3 Scan + +* Added scan detection for new Powerwall 3 systems. API discovery is still underway so pypowerwall currently does not support Powerwall 3s. See https://github.com/jasonacox/Powerwall-Dashboard/issues/387 + +``` +$ python3 -m pypowerwall scan + +pyPowerwall Network Scanner [0.6.3] +Scan local network for Tesla Powerwall Gateways + + Your network appears to be: 10.0.1.0/24 + + Enter Network or press enter to use 10.0.1.0/24: + + Running Scan... + Host: 10.0.1.2 ... OPEN - Not a Powerwall + Host: 10.0.1.5 ... OPEN - Found Powerwall 3 [Currently Unsupported] + Host: 10.0.1.8 ... OPEN - Not a Powerwall + Host: 10.0.1.9 ... OPEN - Found Powerwall 3 [Currently Unsupported] + Done + +Discovered 2 Powerwall Gateway + 10.0.1.5 [Powerwall-3] Firmware Currently Unsupported - See https://tinyurl.com/pw3support + 10.0.1.9 [Powerwall-3] Firmware Currently Unsupported - See https://tinyurl.com/pw3support +``` + ## v0.6.2b - Proxy Grafana Support * Proxy t28: Add a `grafana-dark` style for `PW_STYLE` settings to accommodate placing as iframe in newer Grafana versions (e.g. v9.4.14). See https://github.com/jasonacox/Powerwall-Dashboard/discussions/371. diff --git a/pypowerwall/__init__.py b/pypowerwall/__init__.py index 9cea53d..af55035 100644 --- a/pypowerwall/__init__.py +++ b/pypowerwall/__init__.py @@ -59,7 +59,7 @@ import sys from . import tesla_pb2 # Protobuf definition for vitals -version_tuple = (0, 6, 2) +version_tuple = (0, 6, 3) version = __version__ = '%d.%d.%d' % version_tuple __author__ = 'jasonacox' diff --git a/pypowerwall/scan.py b/pypowerwall/scan.py index fabbd62..0bb5429 100644 --- a/pypowerwall/scan.py +++ b/pypowerwall/scan.py @@ -107,30 +107,50 @@ def scan(color=True, timeout=0.4): print('') print(bold + ' Running Scan...' + dim) # Loop through each host - for addr in ipaddress.IPv4Network(network): - print(dim + '\r Host: ' + subbold + '%s ...' % addr + normal, end='') - a_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) - a_socket.settimeout(timeout) - location = (str(addr), 443) - result_of_check = a_socket.connect_ex(location) - if result_of_check == 0: - print(" OPEN", end='') - # Check to see if it is a Powerwall - url = 'https://%s/api/status' % addr - try: - g = requests.get(url, verify=False, timeout=5) - data = json.loads(g.text) - print(dim + ' - ' + subbold + 'Found Powerwall %s' % data['din']) - print(subbold + ' [Firmware %s]' % data['version']) - discovered[addr] = data['din'] - firmware[addr] = data['version'] - except: - print(dim + ' - Not a Powerwall') - - a_socket.close() + try: + for addr in ipaddress.IPv4Network(network): + print(dim + '\r Host: ' + subbold + '%s ...' % addr + normal, end='') + a_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) + a_socket.settimeout(timeout) + location = (str(addr), 443) + result_of_check = a_socket.connect_ex(location) + if result_of_check == 0: + print(" OPEN", end='') + # Check to see if it is a Powerwall + url = 'https://%s/api/status' % addr + try: + g = requests.get(url, verify=False, timeout=5) + # Check if 404 response + if(g.status_code == 404): + # Check if it is a Powerwall 3 + url = 'https://%s/tedapi/din' % addr + g = requests.get(url, verify=False, timeout=5) + # Expected response from PW3 {"code":403,"error":"Unable to GET to resource","message":"User does not have adequate access rights"} + if "User does not have adequate access rights" in g.text: + # Found PW3 + print(dim + ' - ' + subbold + 'Found Powerwall 3 [Currently Unsupported]') + discovered[addr] = 'Powerwall-3' + firmware[addr] = 'Currently Unsupported - See https://tinyurl.com/pw3support' + else: + # Not a Powerwall + print(dim + ' - Not a Powerwall') + else: + data = json.loads(g.text) + print(dim + ' - ' + subbold + 'Found Powerwall %s' % data['din']) + print(subbold + ' [Firmware %s]' % data['version']) + discovered[addr] = data['din'] + firmware[addr] = data['version'] + except: + print(dim + ' - Not a Powerwall') - print(dim + '\r Done ') - print('') + a_socket.close() + + print(dim + '\r Done ') + print('') + + except KeyboardInterrupt: + print(dim + '\r ** Interrupted by user ** ') + print('') print(normal + 'Discovered %d Powerwall Gateway' % len(discovered)) for ip in discovered: