Skip to content

Commit

Permalink
Fix converting negative integers
Browse files Browse the repository at this point in the history
  • Loading branch information
oyvindwe committed Jul 10, 2024
1 parent 887ce72 commit 256425f
Show file tree
Hide file tree
Showing 7 changed files with 20 additions and 17 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,6 @@
.idea/
*.iml

# Python build
# Python
venv/
dist/
1 change: 1 addition & 0 deletions .python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3.11.1
4 changes: 4 additions & 0 deletions DEVELOPMENT
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
pyenv install
python -m venv venv
source venv/bin/activate
pip install .
14 changes: 2 additions & 12 deletions connectlife/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class LifeConnectAuthError(Exception):
pass


class ConnectLifeApi():
class ConnectLifeApi:
def __init__(self, username: str, password: str):
"""Initialize the auth."""
self._username = username
Expand All @@ -41,7 +41,6 @@ def __init__(self, username: str, password: str):
self._refresh_token: str | None = None
self.appliances: Sequence[ConnectLifeAppliance] = []


async def authenticate(self) -> bool:
"""Test if we can authenticate with the host."""
async with aiohttp.ClientSession() as session:
Expand All @@ -52,22 +51,18 @@ async def authenticate(self) -> bool:
}) as response:
if response.status == 200:
body = await self._json(response)
if "UID" in body:
self.uid = body["UID"]
return "UID" in body and "sessionInfo" in body and "cookieValue" in body["sessionInfo"]
return False

async def login(self) -> None:
await self._fetch_access_token()


async def get_appliances(self) -> Any:
"""Make a request."""
appliances = await self.get_appliances_json()
self.appliances = [ConnectLifeAppliance(self, a) for a in appliances if "deviceId" in a]
return self.appliances


async def get_appliances_json(self) -> Any:
"""Make a request and return the response as text."""
await self._fetch_access_token()
Expand All @@ -83,7 +78,6 @@ async def get_appliances_json(self) -> Any:
raise LifeConnectError(f"Unexpected response: status={response.status}")
return await response.json()


async def update_appliance(self, puid: str, properties: dict[str, str]):
data = {
"puid": puid,
Expand All @@ -100,14 +94,12 @@ async def update_appliance(self, puid: str, properties: dict[str, str]):
_LOGGER.debug(result)
_LOGGER.debug("Updated appliance with puid %s", puid)


async def _fetch_access_token(self):
if self._expires is None:
await self._initial_access_token()
elif self._expires < dt.datetime.now():
await self._refresh_access_token()


async def _initial_access_token(self):
async with aiohttp.ClientSession() as session:
async with session.post(LOGIN_URL, data={
Expand Down Expand Up @@ -141,7 +133,7 @@ async def _initial_access_token(self):
"redirect_uri": OAUTH2_REDIRECT,
"idToken": id_token,
"response_type": "code",
"thirdType":"CDC",
"thirdType": "CDC",
"thirdClientId": uid,
}) as response:
if response.status != 200:
Expand Down Expand Up @@ -170,7 +162,6 @@ async def _initial_access_token(self):
self._expires = dt.datetime.now() + dt.timedelta(0, body["expires_in"] - 90)
self._refresh_token = body["refresh_token"]


async def _refresh_access_token(self) -> None:
async with aiohttp.ClientSession() as session:
async with session.post(OAUTH2_TOKEN, data={
Expand All @@ -190,7 +181,6 @@ async def _refresh_access_token(self) -> None:
# Renew 90 seconds before expiration
self._expires = dt.datetime.now() + dt.timedelta(0, body["expires_in"] - 90)


async def _json(self, response: aiohttp.ClientResponse) -> Any:
# response may have wrong content-type, cannot use response.json()
text = await response.text()
Expand Down
11 changes: 10 additions & 1 deletion connectlife/appliance.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ class DeviceType(StrEnum):
WASHING_MACHINE = "washing_machine"
UNKNOWN = "unknown"


DEVICE_TYPES = {
"003": DeviceType.WASHING_MACHINE,
"004": DeviceType.TUMBLE_DRYER,
Expand All @@ -34,6 +35,7 @@ class DeviceType(StrEnum):
"027": DeviceType.WASHING_MACHINE,
}


class ConnectLifeAppliance:
"""Class representing a single appliance."""

Expand All @@ -55,7 +57,7 @@ def __init__(self, api, data):
self._bind_time = dt.datetime.fromtimestamp(data["bindTime"]/1000) if data["bindTime"] else None
self._use_time = dt.datetime.fromtimestamp(data["useTime"]/1000) if data["useTime"] else None
self._create_time = dt.datetime.fromtimestamp(data["createTime"]/1000) if data["createTime"] else None
self._status_list = {k:int(v) if type(v) == str and v.isdigit() else v for k,v in data["statusList"].items()}
self._status_list = {k: convert(v) for k, v in data["statusList"].items()}
self._device_type = DEVICE_TYPES[self._device_type_code] \
if self._device_type_code in DEVICE_TYPES \
else DeviceType.UNKNOWN
Expand Down Expand Up @@ -131,3 +133,10 @@ def create_time(self) -> dt.datetime | None:
@property
def device_type(self) -> DeviceType:
return self._device_type


def convert(value: str) -> int | str:
try:
return int(value)
except ValueError:
return value
2 changes: 1 addition & 1 deletion connectlife/dump.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ def order_dict(dictionary):
return {k: order_dict(v) if isinstance(v, dict) else v
for k, v in sorted(dictionary.items())}


async def main():
parser = argparse.ArgumentParser(
prog="dump",
Expand All @@ -29,4 +30,3 @@ async def main():

if __name__ == "__main__":
asyncio.run(main())

2 changes: 0 additions & 2 deletions dumps/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,5 +37,3 @@
f.write("## Generated from\n\n")
for filename in files:
f.write(f"- [{filename[:-5]}]({filename})\n")


0 comments on commit 256425f

Please sign in to comment.