Skip to content

Commit

Permalink
only parse meters aggregates response on demand
Browse files Browse the repository at this point in the history
  • Loading branch information
jrester committed Oct 4, 2021
1 parent 1dc7831 commit 4505512
Show file tree
Hide file tree
Showing 11 changed files with 114 additions and 87 deletions.
7 changes: 7 additions & 0 deletions CHANGELOG
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Changelog

## [0.3.11]

### Changed

- meters of `MetersAggregates` can now only be accessed via `get_meter` (https://github.com/home-assistant/core/issues/56660)
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -238,10 +238,14 @@ meters.solar

meters.get_meter(MeterType.SOLAR)
#=> <Meter ...>

```

Available meters are: `solar`, `site`, `load` and `battery`

> Note: if the powerwall you are working with has no solar panels installed `get_meter(MeterType.SOLAR)` returns `None`
> With the attribute `MetersAggregates.meters` you can get the available meters in the response

#### Current power supply/draw

`Meter` provides different methods for checking current power supply/draw:
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
name="tesla_powerwall",
author="Jrester",
author_email="[email protected]",
version='0.3.10',
version='0.3.11',
description="API for Tesla Powerwall",
long_description=long_description,
long_description_content_type="text/markdown",
Expand Down
2 changes: 1 addition & 1 deletion tesla_powerwall/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,4 +31,4 @@
)
from .powerwall import Powerwall

VERSION = "0.3.10"
VERSION = "0.3.11"
6 changes: 4 additions & 2 deletions tesla_powerwall/powerwall.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,9 @@ def get_status(self) -> PowerwallStatus:

def get_device_type(self) -> DeviceType:
"""Returns the device type of the powerwall"""
if self._pin_version is None or self._pin_version >= version.LooseVersion("1.46.0"):
if self._pin_version is None or self._pin_version >= version.LooseVersion(
"1.46.0"
):
return self.get_status().device_type
else:
return DeviceType(
Expand Down Expand Up @@ -173,4 +175,4 @@ def get_api(self):
return self._api

def close(self):
self._api.close()
self._api.close()
16 changes: 6 additions & 10 deletions tesla_powerwall/responses.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,17 +104,13 @@ def is_sending_to(self, precision=DEFAULT_KW_ROUND_PERSICION) -> bool:
class MetersAggregates(Response):
def __init__(self, response):
super().__init__(response)
self.solar = Meter(
MeterType.SOLAR, self.assert_attribute(MeterType.SOLAR.value)
)
self.site = Meter(MeterType.SITE, self.assert_attribute(MeterType.SITE.value))
self.battery = Meter(
MeterType.BATTERY, self.assert_attribute(MeterType.BATTERY.value)
)
self.load = Meter(MeterType.LOAD, self.assert_attribute(MeterType.LOAD.value))
self.meters = [MeterType(key) for key in response.keys()]

def get_meter(self, meter: MeterType) -> Meter:
return getattr(self, meter.value)
if meter in self.meters:
return Meter(meter, self.assert_attribute(meter.value))
else:
return None


class SiteMaster(Response):
Expand Down Expand Up @@ -191,7 +187,7 @@ class PowerwallStatus(Response):

_START_TIME_FORMAT = "%Y-%m-%d %H:%M:%S %z"
_UP_TIME_SECONDS_REGEX = re.compile(
r'^((?P<days>[\.\d]+?)d)?((?P<hours>[\.\d]+?)h)?((?P<minutes>[\.\d]+?)m)?((?P<seconds>[\.\d]+?)s)?$'
r"^((?P<days>[\.\d]+?)d)?((?P<hours>[\.\d]+?)h)?((?P<minutes>[\.\d]+?)m)?((?P<seconds>[\.\d]+?)s)?$"
)

def _parse_uptime_seconds(self, up_time_seconds: str):
Expand Down
2 changes: 1 addition & 1 deletion tests/integration/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@
ENV_POWERWALL_PASSWORD = "POWERWALL_PASSWORD"

POWERWALL_IP = os.environ[ENV_POWERWALL_IP]
POWERWALL_PASSWORD = os.environ[ENV_POWERWALL_PASSWORD]
POWERWALL_PASSWORD = os.environ[ENV_POWERWALL_PASSWORD]
23 changes: 14 additions & 9 deletions tests/integration/test_powerwall.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
from tesla_powerwall.responses import PowerwallStatus
import unittest

from tesla_powerwall import Powerwall, GridStatus, SiteInfo, SiteMaster, MetersAggregates, Meter, MeterType, powerwall
from tesla_powerwall import (
Powerwall,
GridStatus,
SiteInfo,
SiteMaster,
MetersAggregates,
Meter,
MeterType,
powerwall,
)

from tests.integration import POWERWALL_IP, POWERWALL_PASSWORD


class TestPowerwall(unittest.TestCase):
def setUp(self) -> None:
self.powerwall = Powerwall(POWERWALL_IP)
Expand All @@ -21,15 +31,10 @@ def test_get_meters(self) -> None:
meters = self.powerwall.get_meters()
self.assertIsInstance(meters, MetersAggregates)

self.assertIsInstance(meters.site, Meter)
self.assertIsInstance(meters.solar, Meter)
self.assertIsInstance(meters.battery, Meter)
self.assertIsInstance(meters.load, Meter)
self.assertIsInstance(meters.get_meter(MeterType.SOLAR), Meter)
self.assertIsInstance(meters.get_meter(MeterType.BATTERY), Meter)

for meter_type in MeterType:
for meter_type in meters.meters:
meter = meters.get_meter(meter_type)
meter = meters.battery
meter.energy_exported
meter.energy_imported
meter.instant_power
Expand Down Expand Up @@ -71,4 +76,4 @@ def get_status(self) -> None:
self.assertIsInstance(status, PowerwallStatus)
status.up_time_seconds
status.start_time
status.version
status.version
4 changes: 3 additions & 1 deletion tests/unit/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

PREFIX = "tests/unit/fixtures"


def _load_fixtures():
for file in os.listdir("tests/unit/fixtures"):
if file.endswith(".json"):
Expand All @@ -13,4 +14,5 @@ def _load_fixtures():
name = file[:-5].upper() + "_RESPONSE"
globals()[name] = json.loads(f.read())

_load_fixtures()

_load_fixtures()
20 changes: 11 additions & 9 deletions tests/unit/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,23 @@
import responses
from responses import GET, POST, Response, add

from tesla_powerwall import (
API,
AccessDeniedError,
PowerwallUnreachableError,
APIError
)
from tesla_powerwall import API, AccessDeniedError, PowerwallUnreachableError, APIError

from tests.unit import ENDPOINT


class TestAPI(unittest.TestCase):
def setUp(self):
self.api = API(ENDPOINT)

def test_parse_endpoint(self):
test_endpoints = ["1.1.1.1", "http://1.1.1.1", "https://1.1.1.1/api/", "https://1.1.1.1/api", "https://1.1.1.1/"]
test_endpoints = [
"1.1.1.1",
"http://1.1.1.1",
"https://1.1.1.1/api/",
"https://1.1.1.1/api",
"https://1.1.1.1/",
]
for test_endpoint in test_endpoints:
self.assertEqual(self.api._parse_endpoint(test_endpoint), ENDPOINT)

Expand Down Expand Up @@ -48,7 +50,7 @@ def test_process_response(self):
with self.assertRaises(APIError):
self.api._process_response(res)

res._content = b'{}'
res._content = b"{}"
self.assertEqual(self.api._process_response(res), {})

res._content = b'{"response": "ok"}'
Expand Down Expand Up @@ -84,4 +86,4 @@ def test_is_authenticated(self):
self.assertEqual(api.is_authenticated(), False)

def test_url(self):
self.assertEqual(self.api.url("test"), ENDPOINT + "test")
self.assertEqual(self.api.url("test"), ENDPOINT + "test")
Loading

0 comments on commit 4505512

Please sign in to comment.