From a464963524475322023f013d003022f8db5f8df9 Mon Sep 17 00:00:00 2001 From: Jimmy Everling Date: Tue, 25 Jun 2024 21:13:07 +0200 Subject: [PATCH 1/4] Added auto time zone detection --- .../panasonic_cc/pcomfortcloud/apiclient.py | 58 ++++++++++++------- 1 file changed, 38 insertions(+), 20 deletions(-) diff --git a/custom_components/panasonic_cc/pcomfortcloud/apiclient.py b/custom_components/panasonic_cc/pcomfortcloud/apiclient.py index c065723..6d8445d 100644 --- a/custom_components/panasonic_cc/pcomfortcloud/apiclient.py +++ b/custom_components/panasonic_cc/pcomfortcloud/apiclient.py @@ -5,11 +5,26 @@ import hashlib import re import aiohttp +import time from urllib.parse import quote_plus from . import constants from . import panasonicsession +_current_time_zone = None +def get_current_time_zone(): + global _current_time_zone + if _current_time_zone is not None: + return _current_time_zone + local_offset_seconds = -time.timezone + if time.daylight: + local_offset_seconds += 3600 + hours, remainder = divmod(abs(local_offset_seconds), 3600) + minutes = remainder // 60 + _current_time_zone = f"{'+' if local_offset_seconds >= 0 else '-'}{int(hours):02}:{int(minutes):02}" + return _current_time_zone + + class ApiClient(panasonicsession.PanasonicSession): def __init__(self, @@ -74,29 +89,32 @@ def dump(self, device_id): return self.execute_get(self._get_device_status_url(device_guid), "dump", 200) return None - async def history(self, device_id, mode, date, time_zone="+01:00"): + async def history(self, device_id, mode, date, time_zone=""): device_guid = self._device_indexer.get(device_id) + if not device_guid: + return None + if not time_zone: + time_zone = get_current_time_zone() + try: + data_mode = constants.DataMode[mode].value + except KeyError: + raise Exception("Wrong mode parameter") + + payload = { + "deviceGuid": device_guid, + "dataMode": data_mode, + "date": date, + "osTimezone": time_zone + } - if device_guid: - try: - data_mode = constants.DataMode[mode].value - except KeyError: - raise Exception("Wrong mode parameter") - - payload = { - "deviceGuid": device_guid, - "dataMode": data_mode, - "date": date, - "osTimezone": time_zone - } - - json_response = await self.execute_post(self._get_device_history_url(), payload, "history", 200) + json_response = await self.execute_post(self._get_device_history_url(), payload, "history", 200) - return { - 'id': device_id, - 'parameters': self._read_parameters(json_response) - } - return None + return { + 'id': device_id, + 'parameters': self._read_parameters(json_response) + } + + async def get_device(self, device_id): device_guid = self._device_indexer.get(device_id) From fcce188e30bd7f30711253989aed44afd0de6d68 Mon Sep 17 00:00:00 2001 From: Jimmy Everling Date: Tue, 25 Jun 2024 21:29:33 +0200 Subject: [PATCH 2/4] Added wait for settings to be ready before starting session --- .../panasonic_cc/pcomfortcloud/panasonicsession.py | 1 + .../panasonic_cc/pcomfortcloud/panasonicsettings.py | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/custom_components/panasonic_cc/pcomfortcloud/panasonicsession.py b/custom_components/panasonic_cc/pcomfortcloud/panasonicsession.py index e6e9b51..cdba5e8 100644 --- a/custom_components/panasonic_cc/pcomfortcloud/panasonicsession.py +++ b/custom_components/panasonic_cc/pcomfortcloud/panasonicsession.py @@ -48,6 +48,7 @@ def __init__(self, username, password, client: aiohttp.ClientSession, settingsFi async def start_session(self): _LOGGER.debug("Starting Session") + await self._settings.is_ready() if (not self._settings.has_refresh_token): await self._authentication.authenticate(self._username, self._password) if (not self._settings.is_access_token_valid): diff --git a/custom_components/panasonic_cc/pcomfortcloud/panasonicsettings.py b/custom_components/panasonic_cc/pcomfortcloud/panasonicsettings.py index 5cffe39..d17a5ad 100644 --- a/custom_components/panasonic_cc/pcomfortcloud/panasonicsettings.py +++ b/custom_components/panasonic_cc/pcomfortcloud/panasonicsettings.py @@ -35,8 +35,11 @@ def __init__(self, fileName): self._refresh_token = None self._scope = None self._clientId = "" - asyncio.ensure_future(self._load()) + self._loading_task =asyncio.ensure_future(self._load()) + async def is_ready(self): + await self._loading_task + return True async def _load(self): if not os.path.exists(self._fileName): From 66f5d8b036d1cd8aa7b970767b2d3e59956daae7 Mon Sep 17 00:00:00 2001 From: Jimmy Everling Date: Tue, 25 Jun 2024 21:33:56 +0200 Subject: [PATCH 3/4] Version bump --- custom_components/panasonic_cc/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/panasonic_cc/manifest.json b/custom_components/panasonic_cc/manifest.json index d694032..5226d22 100644 --- a/custom_components/panasonic_cc/manifest.json +++ b/custom_components/panasonic_cc/manifest.json @@ -2,7 +2,7 @@ "domain": "panasonic_cc", "name": "Panasonic Comfort Cloud", "after_dependencies": ["http"], - "version": "1.0.45", + "version": "1.0.46", "config_flow": true, "documentation": "https://github.com/sockless-coding/panasonic_cc/", "dependencies": [], From 0fcb54d2a7091edc48bead800cfc4bb93f9a7dd6 Mon Sep 17 00:00:00 2001 From: Jimmy Everling Date: Tue, 25 Jun 2024 21:39:21 +0200 Subject: [PATCH 4/4] Empty the cookie jar before authentication --- .../panasonic_cc/pcomfortcloud/panasonicauthentication.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/panasonic_cc/pcomfortcloud/panasonicauthentication.py b/custom_components/panasonic_cc/pcomfortcloud/panasonicauthentication.py index 0bfcfab..df7e836 100644 --- a/custom_components/panasonic_cc/pcomfortcloud/panasonicauthentication.py +++ b/custom_components/panasonic_cc/pcomfortcloud/panasonicauthentication.py @@ -47,6 +47,7 @@ def __init__(self, client: aiohttp.ClientSession, settings: PanasonicSettings, a async def authenticate(self, username: str, password: str): + self._client.cookie_jar.clear() # generate initial state and code_challenge code_verifier = generate_random_string(43)