From 1a8feb0c710a41e4092e199bed5305d50d4e2b66 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 13 May 2024 01:44:29 +0000 Subject: [PATCH 01/21] friendly model name --- pydaikin/daikin_airbase.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/pydaikin/daikin_airbase.py b/pydaikin/daikin_airbase.py index 17dd936..547293b 100644 --- a/pydaikin/daikin_airbase.py +++ b/pydaikin/daikin_airbase.py @@ -70,6 +70,9 @@ async def init(self): if not self.values: raise DaikinException("Empty values.") self.values.update({**self.DEFAULTS, **self.values}) + # Friendly display the model + if self.values.get("model", None) == "NOTSUPPORT": + self.values["model"] = "Airbase BRP15B61" async def _get_resource(self, path: str, params: Optional[dict] = None): """Make the http request.""" From c131d7fb8ad15cc194749e6a290cbac155201b64 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 13 May 2024 01:45:23 +0000 Subject: [PATCH 02/21] filter dirty --- pydaikin/daikin_base.py | 16 +++++++++++++++- pydaikin/daikin_brp069.py | 1 + 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/pydaikin/daikin_base.py b/pydaikin/daikin_base.py index 1b64126..89c0111 100644 --- a/pydaikin/daikin_base.py +++ b/pydaikin/daikin_base.py @@ -88,7 +88,7 @@ def discover_ip(device_id): device_ip = device_name['ip'] return device_id - def __init__(self, device_id, session: Optional[ClientSession] = None): + def __init__(self, device_id, session: Optional[ClientSession] = None) -> None: """Init the pydaikin appliance, representing one Daikin device.""" self.values = ApplianceValues() self.session = session @@ -175,6 +175,8 @@ def log_sensors(self, file): data.append(('out_temp', self.outside_temperature)) if self.support_compressor_frequency: data.append(('cmp_freq', self.compressor_frequency)) + if self.support_filter_dirty: + data.append(('en_filter_sign', self.filter_dirty)) if self.support_energy_consumption: data.append( ('total_today', self.energy_consumption(ATTR_TOTAL, TIME_TODAY)) @@ -201,6 +203,8 @@ def show_sensors(self): data.append(f'out_temp={int(self.outside_temperature)}°C') if self.support_compressor_frequency: data.append(f'cmp_freq={int(self.compressor_frequency)}Hz') + if self.support_filter_dirty: + data.append(f'en_filter_sign={int(self.filter_dirty)}') if self.support_energy_consumption: data.append( f'total_today={self.energy_consumption(ATTR_TOTAL, TIME_TODAY):.01f}kWh' @@ -281,6 +285,11 @@ def support_compressor_frequency(self) -> bool: """Return True if the device supports compressor frequency.""" return 'cmpfreq' in self.values + @property + def support_filter_dirty(self) -> bool: + """Return True if the device supports dirty filter notification.""" + return 'en_filter_sign' in self.values + @property def support_energy_consumption(self) -> bool: """Return True if the device supports energy consumption monitoring.""" @@ -306,6 +315,11 @@ def compressor_frequency(self) -> Optional[float]: """Return current compressor frequency.""" return self._parse_number('cmpfreq') + @property + def filter_dirty(self) -> Optional[float]: + """Return current status of the filter.""" + return self._parse_number('en_filter_sign') + @property def humidity(self) -> Optional[float]: """Return current humidity.""" diff --git a/pydaikin/daikin_brp069.py b/pydaikin/daikin_brp069.py index bcdcd1a..7df5c82 100644 --- a/pydaikin/daikin_brp069.py +++ b/pydaikin/daikin_brp069.py @@ -114,6 +114,7 @@ class DaikinBRP069(Appliance): 'en_hol': 'away_mode', 'cur': 'internal clock', 'adv': 'advanced mode', + 'filter_sign_info': 'filter dirty' } async def init(self): From 37268e7b33795be0b2a9484166771a236af8db2c Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 13 May 2024 01:46:20 +0000 Subject: [PATCH 03/21] handle outdoor tempreture missing --- pydaikin/daikin_airbase.py | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/pydaikin/daikin_airbase.py b/pydaikin/daikin_airbase.py index 547293b..3d023dd 100644 --- a/pydaikin/daikin_airbase.py +++ b/pydaikin/daikin_airbase.py @@ -90,9 +90,15 @@ def support_swing_mode(self): return False @property - def support_outside_temperature(self): - """AirBase unit returns otemp if master controller starts before it.""" - return True + def outside_temperature(self): + """ + AirBase unit returns otemp if master controller starts before it. + + No Outside Thermometor returns a '-' (Non Number). + Return current outside temperature if available. + """ + value = self.values.get('otemp') + return self._parse_number('otemp') if value != '-' else None @property def support_zone_temperature(self): From 9f633de751f58384b122d9be295c2a262c3795c9 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 13 May 2024 01:57:48 +0000 Subject: [PATCH 04/21] support enabled zones --- pydaikin/daikin_airbase.py | 5 ++++- pydaikin/daikin_base.py | 10 ++++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/pydaikin/daikin_airbase.py b/pydaikin/daikin_airbase.py index 3d023dd..1154ead 100644 --- a/pydaikin/daikin_airbase.py +++ b/pydaikin/daikin_airbase.py @@ -183,8 +183,11 @@ def zones(self): """Return list of zones.""" if not self.values.get("zone_name"): return None + enabled_zones = len(self.represent("zone_name")[1]) + if self.support_zone_count: + enabled_zones = int(self.zone_count) #float to int zone_onoff = self.represent("zone_onoff")[1] - zone_list = self.represent("zone_name")[1] + zone_list = self.represent("zone_name")[1][:enabled_zones] # Slicing to limit zones if self.support_zone_temperature: mode = self.values["mode"] diff --git a/pydaikin/daikin_base.py b/pydaikin/daikin_base.py index 89c0111..9d1a298 100644 --- a/pydaikin/daikin_base.py +++ b/pydaikin/daikin_base.py @@ -290,6 +290,11 @@ def support_filter_dirty(self) -> bool: """Return True if the device supports dirty filter notification.""" return 'en_filter_sign' in self.values + @property + def support_zone_count(self) -> bool: + """Return True if the device supports count of active zones.""" + return 'en_zone' in self.values + @property def support_energy_consumption(self) -> bool: """Return True if the device supports energy consumption monitoring.""" @@ -320,6 +325,11 @@ def filter_dirty(self) -> Optional[float]: """Return current status of the filter.""" return self._parse_number('en_filter_sign') + @property + def zone_count(self) -> Optional[float]: + """Return number of enabled zones.""" + return self._parse_number('en_zone') + @property def humidity(self) -> Optional[float]: """Return current humidity.""" From 0d0c4bb6e83667f398c2820712eb046d7f23d31c Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 20 May 2024 06:36:35 +0000 Subject: [PATCH 05/21] Create session if not passed --- pydaikin/daikin_base.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pydaikin/daikin_base.py b/pydaikin/daikin_base.py index 9d1a298..ab25909 100644 --- a/pydaikin/daikin_base.py +++ b/pydaikin/daikin_base.py @@ -91,7 +91,7 @@ def discover_ip(device_id): def __init__(self, device_id, session: Optional[ClientSession] = None) -> None: """Init the pydaikin appliance, representing one Daikin device.""" self.values = ApplianceValues() - self.session = session + self.session = session if session is not None else ClientSession() self._energy_consumption_history = defaultdict(list) if session: self.device_ip = device_id From f19e876cc269899be09d290fd931410addd176a0 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 20 May 2024 06:38:49 +0000 Subject: [PATCH 06/21] move from retry to tenacity --- pydaikin/daikin_base.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/pydaikin/daikin_base.py b/pydaikin/daikin_base.py index ab25909..b285118 100644 --- a/pydaikin/daikin_base.py +++ b/pydaikin/daikin_base.py @@ -9,8 +9,7 @@ from urllib.parse import unquote from aiohttp import ClientSession -from aiohttp.web_exceptions import HTTPForbidden -from retry import retry +from tenacity import before_sleep_log, retry, retry_if_exception_type, stop_after_attempt, wait_fixed from .discovery import get_name from .power import ATTR_COOL, ATTR_HEAT, ATTR_TOTAL, TIME_TODAY, DaikinPowerMixin @@ -113,7 +112,7 @@ async def init(self): # Re-defined in all sub-classes raise NotImplementedError - @retry(tries=3, delay=1) + @retry(reraise=True, wait=wait_fixed(1), stop=stop_after_attempt(3), retry=retry_if_exception_type(ServerDisconnectedError),before_sleep=before_sleep_log(_LOGGER, logging.DEBUG)) async def _get_resource(self, path: str, params: Optional[dict] = None): """Make the http request.""" if params is None: From 13c40fdfcc3c000d0549ef707033fb67cfebdce6 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 20 May 2024 06:40:23 +0000 Subject: [PATCH 07/21] use parent session --- pydaikin/daikin_base.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/pydaikin/daikin_base.py b/pydaikin/daikin_base.py index b285118..47ace38 100644 --- a/pydaikin/daikin_base.py +++ b/pydaikin/daikin_base.py @@ -118,13 +118,8 @@ async def _get_resource(self, path: str, params: Optional[dict] = None): if params is None: params = {} - if self.session is None: - session = ClientSession() - else: - session = self.session - - async with session as client_session, self.request_semaphore: - async with client_session.get( + async with self.request_semaphore: + async with self.session.get( f'{self.base_url}/{path}', params=params ) as resp: if resp.status == 403: From ace3ae61b084542ae08074cf2536e51a33f25b4c Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 20 May 2024 06:41:48 +0000 Subject: [PATCH 08/21] handle airbase fallback --- pydaikin/daikin_base.py | 34 +++++++++++++++++++++++++--------- pydaikin/factory.py | 23 +++++++++++++++++------ 2 files changed, 42 insertions(+), 15 deletions(-) diff --git a/pydaikin/daikin_base.py b/pydaikin/daikin_base.py index 47ace38..3e4c9de 100644 --- a/pydaikin/daikin_base.py +++ b/pydaikin/daikin_base.py @@ -9,6 +9,8 @@ from urllib.parse import unquote from aiohttp import ClientSession +from aiohttp.web_exceptions import HTTPError,HTTPForbidden +from aiohttp.client_exceptions import ServerDisconnectedError from tenacity import before_sleep_log, retry, retry_if_exception_type, stop_after_attempt, wait_fixed from .discovery import get_name @@ -118,14 +120,23 @@ async def _get_resource(self, path: str, params: Optional[dict] = None): if params is None: params = {} + _LOGGER.debug("Calling: %s/%s %s",self.base_url, path, params) + + # cannot manage session on outer async with or this will close the session + # passed to pydaikin (homeassistant for instance) async with self.request_semaphore: async with self.session.get( f'{self.base_url}/{path}', params=params - ) as resp: - if resp.status == 403: - raise HTTPForbidden - assert resp.status == 200, f"Response code is {resp.status}" - return self.parse_response(await resp.text()) + ) as response: + if response.status == 403: + raise HTTPForbidden(reason=f"HTTP 403 Forbidden for {response.url}") + #Airbase returns a 404 response on invalid urls but requires fallback + if response.status == 404: + _LOGGER.debug("HTTP 404 Not Found for %s", response.url) + return {} #return an empty dict to indicate successful connection but bad data + if response.status != 200: + raise HTTPError(reason=f"Unexpected HTTP status code {response.status} for {response.url}") + return self.parse_response(await response.text()) async def update_status(self, resources=None): """Update status from resources.""" @@ -137,10 +148,15 @@ async def update_status(self, resources=None): if self.values.should_resource_be_updated(resource) ] _LOGGER.debug("Updating %s", resources) - async with asyncio.TaskGroup() as tg: - tasks = [ - tg.create_task(self._get_resource(resource)) for resource in resources - ] + + try: + async with asyncio.TaskGroup() as tg: + tasks = [ + tg.create_task(self._get_resource(resource)) for resource in resources + ] + except ExceptionGroup as eg: + for exc in eg.exceptions: + _LOGGER.error("Exception in TaskGroup: %s", exc) for resource, task in zip(resources, tasks): self.values.update_by_resource(resource, task.result()) diff --git a/pydaikin/factory.py b/pydaikin/factory.py index af57e50..d622d3b 100644 --- a/pydaikin/factory.py +++ b/pydaikin/factory.py @@ -1,5 +1,6 @@ "Factory to generate Pydaikin complete objects" +import logging from typing import Optional from aiohttp import ClientSession @@ -11,6 +12,9 @@ from .daikin_skyfi import DaikinSkyFi from .exceptions import DaikinException +from aiohttp.web_exceptions import HTTPNotFound + +_LOGGER = logging.getLogger(__name__) class DaikinFactory: # pylint: disable=too-few-public-methods "Factory object generating instantiated instances of Appliance" @@ -31,7 +35,7 @@ async def __init__( **kwargs, ) -> None: """Factory to init the corresponding Daikin class.""" - + # _LOGGER.warning("device_id: %s password: %s key: %s kwargs: %s",device_id, password, key, kwargs) if password is not None: self._generated_object = DaikinSkyFi(device_id, session, password=password) elif key is not None: @@ -42,11 +46,16 @@ async def __init__( uuid=kwargs.get('uuid'), ) else: # special case for BRP069 and AirBase - self._generated_object = DaikinBRP069(device_id, session) - await self._generated_object.update_status( - self._generated_object.HTTP_RESOURCES[:1] - ) - if not self._generated_object.values: + try: + _LOGGER.debug("Trying connection to BRP069") + self._generated_object = DaikinBRP069(device_id, session) + await self._generated_object.update_status( + self._generated_object.HTTP_RESOURCES[:1] + ) + if not self._generated_object.values: + raise DaikinException("Empty Values.") + except (HTTPNotFound,DaikinException) as err: + _LOGGER.debug("Falling back to AirBase: %s", err) self._generated_object = DaikinAirBase(device_id, session) await self._generated_object.init() @@ -55,3 +64,5 @@ async def __init__( raise DaikinException( f"Error creating device, {device_id} is not supported." ) + + _LOGGER.debug("Daikin generated object: %s", self._generated_object) From 23b361bb752ab14b65d1fd3fab44d16c83e8af17 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 20 May 2024 06:42:03 +0000 Subject: [PATCH 09/21] version bump --- .bumpversion.cfg | 2 +- setup.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 66f232e..61716c8 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2.11.1 +current_version = 2.11.2 commit = True tag = True files = setup.py diff --git a/setup.py b/setup.py index 1f1e770..51b9834 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='pydaikin', - version='2.11.1', + version='2.11.2', description='Python Daikin HVAC appliances interface', long_description=long_description, long_description_content_type="text/markdown", From 5bda49ac57bc4ef7ae6459d75aed23b58c6c2fd7 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Mon, 20 May 2024 06:43:43 +0000 Subject: [PATCH 10/21] cleanup --- pydaikin/daikin_airbase.py | 2 +- pydaikin/factory.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/pydaikin/daikin_airbase.py b/pydaikin/daikin_airbase.py index 1154ead..f3d885f 100644 --- a/pydaikin/daikin_airbase.py +++ b/pydaikin/daikin_airbase.py @@ -59,7 +59,7 @@ def parse_response(response_body): def __init__( self, device_id, session=None - ): # pylint:disable=useless-super-delegation + ) -> None: # pylint:disable=useless-super-delegation """Init the pydaikin appliance, representing one Daikin AirBase (BRP15B61) device.""" super().__init__(device_id, session) diff --git a/pydaikin/factory.py b/pydaikin/factory.py index d622d3b..b03578e 100644 --- a/pydaikin/factory.py +++ b/pydaikin/factory.py @@ -35,7 +35,7 @@ async def __init__( **kwargs, ) -> None: """Factory to init the corresponding Daikin class.""" - # _LOGGER.warning("device_id: %s password: %s key: %s kwargs: %s",device_id, password, key, kwargs) + if password is not None: self._generated_object = DaikinSkyFi(device_id, session, password=password) elif key is not None: From eaa7ff88ff9886f75f1f7ef5f9d78da5a5928b24 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Tue, 21 May 2024 00:50:52 +0000 Subject: [PATCH 11/21] handle filter being cleaned --- pydaikin/daikin_base.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/pydaikin/daikin_base.py b/pydaikin/daikin_base.py index 3e4c9de..2a02338 100644 --- a/pydaikin/daikin_base.py +++ b/pydaikin/daikin_base.py @@ -297,8 +297,12 @@ def support_compressor_frequency(self) -> bool: @property def support_filter_dirty(self) -> bool: - """Return True if the device supports dirty filter notification.""" - return 'en_filter_sign' in self.values + """Return True if the device supports dirty filter notification and it is turned on.""" + return ( + 'en_filter_sign' in self.values and + 'filter_sign_info' in self.values and + int(self._parse_number('en_filter_sign')) == 1 + ) @property def support_zone_count(self) -> bool: @@ -333,7 +337,7 @@ def compressor_frequency(self) -> Optional[float]: @property def filter_dirty(self) -> Optional[float]: """Return current status of the filter.""" - return self._parse_number('en_filter_sign') + return self._parse_number('filter_sign_info') @property def zone_count(self) -> Optional[float]: From fde548eb80a654135c41cd275320cb169fa29885 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 00:56:12 +0000 Subject: [PATCH 12/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pydaikin/daikin_airbase.py | 6 ++++-- pydaikin/daikin_base.py | 39 +++++++++++++++++++++++++++----------- pydaikin/daikin_brp069.py | 2 +- pydaikin/factory.py | 6 +++--- 4 files changed, 36 insertions(+), 17 deletions(-) diff --git a/pydaikin/daikin_airbase.py b/pydaikin/daikin_airbase.py index f3d885f..b556262 100644 --- a/pydaikin/daikin_airbase.py +++ b/pydaikin/daikin_airbase.py @@ -185,9 +185,11 @@ def zones(self): return None enabled_zones = len(self.represent("zone_name")[1]) if self.support_zone_count: - enabled_zones = int(self.zone_count) #float to int + enabled_zones = int(self.zone_count) # float to int zone_onoff = self.represent("zone_onoff")[1] - zone_list = self.represent("zone_name")[1][:enabled_zones] # Slicing to limit zones + zone_list = self.represent("zone_name")[1][ + :enabled_zones + ] # Slicing to limit zones if self.support_zone_temperature: mode = self.values["mode"] diff --git a/pydaikin/daikin_base.py b/pydaikin/daikin_base.py index 2a02338..14f2101 100644 --- a/pydaikin/daikin_base.py +++ b/pydaikin/daikin_base.py @@ -9,9 +9,15 @@ from urllib.parse import unquote from aiohttp import ClientSession -from aiohttp.web_exceptions import HTTPError,HTTPForbidden from aiohttp.client_exceptions import ServerDisconnectedError -from tenacity import before_sleep_log, retry, retry_if_exception_type, stop_after_attempt, wait_fixed +from aiohttp.web_exceptions import HTTPError, HTTPForbidden +from tenacity import ( + before_sleep_log, + retry, + retry_if_exception_type, + stop_after_attempt, + wait_fixed, +) from .discovery import get_name from .power import ATTR_COOL, ATTR_HEAT, ATTR_TOTAL, TIME_TODAY, DaikinPowerMixin @@ -114,13 +120,19 @@ async def init(self): # Re-defined in all sub-classes raise NotImplementedError - @retry(reraise=True, wait=wait_fixed(1), stop=stop_after_attempt(3), retry=retry_if_exception_type(ServerDisconnectedError),before_sleep=before_sleep_log(_LOGGER, logging.DEBUG)) + @retry( + reraise=True, + wait=wait_fixed(1), + stop=stop_after_attempt(3), + retry=retry_if_exception_type(ServerDisconnectedError), + before_sleep=before_sleep_log(_LOGGER, logging.DEBUG), + ) async def _get_resource(self, path: str, params: Optional[dict] = None): """Make the http request.""" if params is None: params = {} - _LOGGER.debug("Calling: %s/%s %s",self.base_url, path, params) + _LOGGER.debug("Calling: %s/%s %s", self.base_url, path, params) # cannot manage session on outer async with or this will close the session # passed to pydaikin (homeassistant for instance) @@ -130,12 +142,16 @@ async def _get_resource(self, path: str, params: Optional[dict] = None): ) as response: if response.status == 403: raise HTTPForbidden(reason=f"HTTP 403 Forbidden for {response.url}") - #Airbase returns a 404 response on invalid urls but requires fallback + # Airbase returns a 404 response on invalid urls but requires fallback if response.status == 404: _LOGGER.debug("HTTP 404 Not Found for %s", response.url) - return {} #return an empty dict to indicate successful connection but bad data + return ( + {} + ) # return an empty dict to indicate successful connection but bad data if response.status != 200: - raise HTTPError(reason=f"Unexpected HTTP status code {response.status} for {response.url}") + raise HTTPError( + reason=f"Unexpected HTTP status code {response.status} for {response.url}" + ) return self.parse_response(await response.text()) async def update_status(self, resources=None): @@ -152,7 +168,8 @@ async def update_status(self, resources=None): try: async with asyncio.TaskGroup() as tg: tasks = [ - tg.create_task(self._get_resource(resource)) for resource in resources + tg.create_task(self._get_resource(resource)) + for resource in resources ] except ExceptionGroup as eg: for exc in eg.exceptions: @@ -299,9 +316,9 @@ def support_compressor_frequency(self) -> bool: def support_filter_dirty(self) -> bool: """Return True if the device supports dirty filter notification and it is turned on.""" return ( - 'en_filter_sign' in self.values and - 'filter_sign_info' in self.values and - int(self._parse_number('en_filter_sign')) == 1 + 'en_filter_sign' in self.values + and 'filter_sign_info' in self.values + and int(self._parse_number('en_filter_sign')) == 1 ) @property diff --git a/pydaikin/daikin_brp069.py b/pydaikin/daikin_brp069.py index 7df5c82..63be396 100644 --- a/pydaikin/daikin_brp069.py +++ b/pydaikin/daikin_brp069.py @@ -114,7 +114,7 @@ class DaikinBRP069(Appliance): 'en_hol': 'away_mode', 'cur': 'internal clock', 'adv': 'advanced mode', - 'filter_sign_info': 'filter dirty' + 'filter_sign_info': 'filter dirty', } async def init(self): diff --git a/pydaikin/factory.py b/pydaikin/factory.py index b03578e..694b120 100644 --- a/pydaikin/factory.py +++ b/pydaikin/factory.py @@ -4,6 +4,7 @@ from typing import Optional from aiohttp import ClientSession +from aiohttp.web_exceptions import HTTPNotFound from .daikin_airbase import DaikinAirBase from .daikin_base import Appliance @@ -12,10 +13,9 @@ from .daikin_skyfi import DaikinSkyFi from .exceptions import DaikinException -from aiohttp.web_exceptions import HTTPNotFound - _LOGGER = logging.getLogger(__name__) + class DaikinFactory: # pylint: disable=too-few-public-methods "Factory object generating instantiated instances of Appliance" _generated_object: Appliance @@ -54,7 +54,7 @@ async def __init__( ) if not self._generated_object.values: raise DaikinException("Empty Values.") - except (HTTPNotFound,DaikinException) as err: + except (HTTPNotFound, DaikinException) as err: _LOGGER.debug("Falling back to AirBase: %s", err) self._generated_object = DaikinAirBase(device_id, session) From a767ecbe5eca6280eafcf9db0d9ed0e3059553e4 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Tue, 21 May 2024 01:05:35 +0000 Subject: [PATCH 13/21] useless-parent-delegation --- pydaikin/daikin_airbase.py | 4 +--- pydaikin/daikin_brp072c.py | 2 +- pydaikin/daikin_skyfi.py | 2 +- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/pydaikin/daikin_airbase.py b/pydaikin/daikin_airbase.py index b556262..9a03b06 100644 --- a/pydaikin/daikin_airbase.py +++ b/pydaikin/daikin_airbase.py @@ -57,9 +57,7 @@ def parse_response(response_body): return response - def __init__( - self, device_id, session=None - ) -> None: # pylint:disable=useless-super-delegation + def __init__(self, device_id, session=None) -> None: # pylint:disable=useless-parent-delegation """Init the pydaikin appliance, representing one Daikin AirBase (BRP15B61) device.""" super().__init__(device_id, session) diff --git a/pydaikin/daikin_brp072c.py b/pydaikin/daikin_brp072c.py index 84f3cdc..5f56ce1 100644 --- a/pydaikin/daikin_brp072c.py +++ b/pydaikin/daikin_brp072c.py @@ -12,7 +12,7 @@ class DaikinBRP072C(DaikinBRP069): """Daikin class for BRP072Cxx units.""" - def __init__(self, device_id, session=None, key=None, uuid=None): + def __init__(self, device_id, session=None, key=None, uuid=None) -> None: """Init the pydaikin appliance, representing one Daikin AirBase (BRP15B61) device.""" super().__init__(device_id, session) diff --git a/pydaikin/daikin_skyfi.py b/pydaikin/daikin_skyfi.py index 7855bc7..5222cb2 100644 --- a/pydaikin/daikin_skyfi.py +++ b/pydaikin/daikin_skyfi.py @@ -47,7 +47,7 @@ class DaikinSkyFi(Appliance): }, } - def __init__(self, device_id, session=None, password=None): + def __init__(self, device_id, session=None, password=None) -> None: """Init the pydaikin appliance, representing one Daikin SkyFi device.""" super().__init__(device_id, session) self.device_ip = f'{self.device_ip}:2000' From 5973258fa4c9b0b3618b53ea835be6edc057a680 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Tue, 21 May 2024 01:05:32 +0000 Subject: [PATCH 14/21] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- pydaikin/daikin_airbase.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pydaikin/daikin_airbase.py b/pydaikin/daikin_airbase.py index 9a03b06..cdacd4c 100644 --- a/pydaikin/daikin_airbase.py +++ b/pydaikin/daikin_airbase.py @@ -57,7 +57,9 @@ def parse_response(response_body): return response - def __init__(self, device_id, session=None) -> None: # pylint:disable=useless-parent-delegation + def __init__( + self, device_id, session=None + ) -> None: # pylint:disable=useless-parent-delegation """Init the pydaikin appliance, representing one Daikin AirBase (BRP15B61) device.""" super().__init__(device_id, session) From feaf57fb007df713dc97ac32cb41993a4669599a Mon Sep 17 00:00:00 2001 From: kingy444 Date: Tue, 21 May 2024 01:10:42 +0000 Subject: [PATCH 15/21] add tenacity to requirements --- requirements.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index ff26563..c63ace9 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,4 +1,4 @@ netifaces aiohttp urllib3 -retry \ No newline at end of file +tenacity \ No newline at end of file From 32192a6b8a1891c64da6a2d996fd2f71b297198c Mon Sep 17 00:00:00 2001 From: kingy444 Date: Fri, 24 May 2024 15:04:25 +1000 Subject: [PATCH 16/21] revert bump Co-authored-by: Fredrik Erlandsson --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 51b9834..1f1e770 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ setup( name='pydaikin', - version='2.11.2', + version='2.11.1', description='Python Daikin HVAC appliances interface', long_description=long_description, long_description_content_type="text/markdown", From 30a53d9efaf99e790c834ee17a9308a0b387fc0d Mon Sep 17 00:00:00 2001 From: kingy444 Date: Fri, 24 May 2024 15:04:43 +1000 Subject: [PATCH 17/21] Roll back to 2.11.1 Co-authored-by: Fredrik Erlandsson --- .bumpversion.cfg | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 61716c8..66f232e 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 2.11.2 +current_version = 2.11.1 commit = True tag = True files = setup.py From 5b1fb3872ab03d7c1c83fd08d1ef731cc5c1ca21 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Fri, 24 May 2024 05:09:19 +0000 Subject: [PATCH 18/21] add tenacity to pre-commit --- .pre-commit-config.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 831b199..78f0ca8 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -29,7 +29,7 @@ repos: - aiohttp==3.7.3 - netifaces==0.11.0 - urllib3==1.26.3 - - retry==0.9.2 + - tenacity==8.2.3 exclude: 'tests/' args: - --ignore=setup.py From 109beea8f3d939af595198e67359639bb6cc7977 Mon Sep 17 00:00:00 2001 From: kingy444 Date: Fri, 24 May 2024 05:21:28 +0000 Subject: [PATCH 19/21] pylint disable c-extension-no-member --- pydaikin/discovery.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/pydaikin/discovery.py b/pydaikin/discovery.py index 48fc404..8582858 100644 --- a/pydaikin/discovery.py +++ b/pydaikin/discovery.py @@ -21,7 +21,7 @@ class Discovery: # pylint: disable=too-few-public-methods """Discovery class.""" - def __init__(self): + def __init__(self) -> None: sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) sock.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1) sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) @@ -37,11 +37,13 @@ def poll(self, stop_if_found=None, ip=None): # pylint: disable=invalid-name broadcast_ips = [ip] else: # get all IPv4 definitions in the system + # pylint: disable=c-extension-no-member net_groups = [ netifaces.ifaddresses(i)[netifaces.AF_INET] for i in netifaces.interfaces() if netifaces.AF_INET in netifaces.ifaddresses(i) ] + # pylint: enable=c-extension-no-member # flatten the previous list net_ips = [item for sublist in net_groups for item in sublist] From 04ac4ec71be4df32c051e72dee51636660ce6d05 Mon Sep 17 00:00:00 2001 From: Fredrik Erlandsson Date: Fri, 24 May 2024 13:07:48 +0200 Subject: [PATCH 20/21] Apply suggestions from code review Fix pylint issues in pre-commit --- .pre-commit-config.yaml | 1 + pydaikin/daikin_airbase.py | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 78f0ca8..7b896f1 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -33,3 +33,4 @@ repos: exclude: 'tests/' args: - --ignore=setup.py + - --extension-pkg-allow-list=netifaces diff --git a/pydaikin/daikin_airbase.py b/pydaikin/daikin_airbase.py index cdacd4c..227ccba 100644 --- a/pydaikin/daikin_airbase.py +++ b/pydaikin/daikin_airbase.py @@ -57,9 +57,9 @@ def parse_response(response_body): return response - def __init__( + def __init__( # pylint:disable=useless-parent-delegation self, device_id, session=None - ) -> None: # pylint:disable=useless-parent-delegation + ) -> None: """Init the pydaikin appliance, representing one Daikin AirBase (BRP15B61) device.""" super().__init__(device_id, session) From cbdd1a83d126d15b818a1d9ed2c23f6cd54b7d7f Mon Sep 17 00:00:00 2001 From: Fredrik Erlandsson Date: Fri, 24 May 2024 13:14:02 +0200 Subject: [PATCH 21/21] Remover extra pylint rows --- pydaikin/discovery.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/pydaikin/discovery.py b/pydaikin/discovery.py index 8582858..15cb93b 100644 --- a/pydaikin/discovery.py +++ b/pydaikin/discovery.py @@ -37,13 +37,11 @@ def poll(self, stop_if_found=None, ip=None): # pylint: disable=invalid-name broadcast_ips = [ip] else: # get all IPv4 definitions in the system - # pylint: disable=c-extension-no-member net_groups = [ netifaces.ifaddresses(i)[netifaces.AF_INET] for i in netifaces.interfaces() if netifaces.AF_INET in netifaces.ifaddresses(i) ] - # pylint: enable=c-extension-no-member # flatten the previous list net_ips = [item for sublist in net_groups for item in sublist]