From e1c8bc5835092e1d83e573427eb833f3b932af2f Mon Sep 17 00:00:00 2001 From: Andre Basche Date: Sun, 16 Jul 2023 04:42:29 +0200 Subject: [PATCH] Reduce complexity and line length for flake8 --- .github/workflows/python-check.yml | 4 +-- pyhon/appliance.py | 43 +++++++++++------------ pyhon/connection/handler/base.py | 6 ++-- pyhon/const.py | 6 ++-- pyhon/parameter/program.py | 16 +++++---- pyhon/parameter/range.py | 5 ++- pyhon/printer.py | 31 +++++++---------- pyhon/rules.py | 55 +++++++++++++++++++----------- 8 files changed, 89 insertions(+), 77 deletions(-) diff --git a/.github/workflows/python-check.yml b/.github/workflows/python-check.yml index 53a37b0..a0e7113 100644 --- a/.github/workflows/python-check.yml +++ b/.github/workflows/python-check.yml @@ -28,9 +28,7 @@ jobs: python -m pip install -r requirements_dev.txt - name: Lint with flake8 run: | - # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=88 --statistics + flake8 . --count --max-complexity=7 --max-line-length=88 --statistics - name: Type check with mypy run: | mypy pyhon/ diff --git a/pyhon/appliance.py b/pyhon/appliance.py index 05b4b8d..f1a4c8c 100644 --- a/pyhon/appliance.py +++ b/pyhon/appliance.py @@ -188,12 +188,8 @@ class HonAppliance: async def update(self, force: bool = False) -> None: now = datetime.now() - if ( - force - or not self._last_update - or self._last_update - < now - timedelta(seconds=self._MINIMAL_UPDATE_INTERVAL) - ): + min_age = now - timedelta(seconds=self._MINIMAL_UPDATE_INTERVAL) + if force or not self._last_update or self._last_update < min_age: self._last_update = now await self.load_attributes() self.sync_params_to_command("settings") @@ -272,18 +268,23 @@ class HonAppliance: for command, data in self.commands.items(): if command == main or target and command not in target: continue - for name, parameter in data.parameters.items(): - if base_value := base.parameters.get(name): - if isinstance(base_value, HonParameterRange) and isinstance( - parameter, HonParameterRange - ): - parameter.max = base_value.max - parameter.min = base_value.min - parameter.step = base_value.step - elif isinstance(parameter, HonParameterRange): - parameter.max = int(base_value.value) - parameter.min = int(base_value.value) - parameter.step = 1 - elif isinstance(parameter, HonParameterEnum): - parameter.values = base_value.values - parameter.value = base_value.value + + for name, target_param in data.parameters.items(): + if not (base_param := base.parameters.get(name)): + return + self.sync_parameter(base_param, target_param) + + def sync_parameter(self, main: Parameter, target: Parameter) -> None: + if isinstance(main, HonParameterRange) and isinstance( + target, HonParameterRange + ): + target.max = main.max + target.min = main.min + target.step = main.step + elif isinstance(target, HonParameterRange): + target.max = int(main.value) + target.min = int(main.value) + target.step = 1 + elif isinstance(target, HonParameterEnum): + target.values = main.values + target.value = main.value diff --git a/pyhon/connection/handler/base.py b/pyhon/connection/handler/base.py index 9e5c77b..6e169e1 100644 --- a/pyhon/connection/handler/base.py +++ b/pyhon/connection/handler/base.py @@ -60,7 +60,8 @@ class ConnectionHandler: if self._session is None: raise exceptions.NoSessionException() response: aiohttp.ClientResponse - async with self._intercept(self._session.get, *args, **kwargs) as response: # type: ignore[arg-type] + args = self._session.get, *args + async with self._intercept(*args, **kwargs) as response: yield response @asynccontextmanager @@ -70,7 +71,8 @@ class ConnectionHandler: if self._session is None: raise exceptions.NoSessionException() response: aiohttp.ClientResponse - async with self._intercept(self._session.post, *args, **kwargs) as response: # type: ignore[arg-type] + args = self._session.post, *args + async with self._intercept(*args, **kwargs) as response: yield response async def close(self) -> None: diff --git a/pyhon/const.py b/pyhon/const.py index 49af0bf..4f97435 100644 --- a/pyhon/const.py +++ b/pyhon/const.py @@ -2,8 +2,10 @@ AUTH_API = "https://account2.hon-smarthome.com" API_URL = "https://api-iot.he.services" API_KEY = "GRCqFhC6Gk@ikWXm1RmnSmX1cm,MxY-configuration" APP = "hon" -# All seen id's (different accounts, different devices) are the same, so I guess this hash is static -CLIENT_ID = "3MVG9QDx8IX8nP5T2Ha8ofvlmjLZl5L_gvfbT9.HJvpHGKoAS_dcMN8LYpTSYeVFCraUnV.2Ag1Ki7m4znVO6" +CLIENT_ID = ( + "3MVG9QDx8IX8nP5T2Ha8ofvlmjLZl5L_gvfbT9." + "HJvpHGKoAS_dcMN8LYpTSYeVFCraUnV.2Ag1Ki7m4znVO6" +) APP_VERSION = "2.1.2" OS_VERSION = 31 OS = "android" diff --git a/pyhon/parameter/program.py b/pyhon/parameter/program.py index 4ed2004..83b843f 100644 --- a/pyhon/parameter/program.py +++ b/pyhon/parameter/program.py @@ -41,13 +41,15 @@ class HonParameterProgram(HonParameterEnum): @property def ids(self) -> Dict[int, str]: - values = { - int(p.parameters["prCode"].value): n - for i, (n, p) in enumerate(self._programs.items()) - if "iot_" not in n - and p.parameters.get("prCode") - and not ((fav := p.parameters.get("favourite")) and fav.value == "1") - } + values: Dict[int, str] = {} + for name, parameter in self._programs.items(): + if "iot_" in name: + continue + if parameter.parameters.get("prCode"): + continue + if (fav := parameter.parameters.get("favourite")) and fav.value == "1": + continue + values[int(parameter.parameters["prCode"].value)] = name return dict(sorted(values.items())) def set_value(self, value: str) -> None: diff --git a/pyhon/parameter/range.py b/pyhon/parameter/range.py index c51642c..6d8f9e9 100644 --- a/pyhon/parameter/range.py +++ b/pyhon/parameter/range.py @@ -64,9 +64,8 @@ class HonParameterRange(HonParameter): self._value = value self.check_trigger(value) else: - raise ValueError( - f"Allowed: min {self.min} max {self.max} step {self.step} But was: {value}" - ) + allowed = f"min {self.min} max {self.max} step {self.step}" + raise ValueError(f"Allowed: {allowed} But was: {value}") @property def values(self) -> List[str]: diff --git a/pyhon/printer.py b/pyhon/printer.py index 395c531..ac7d66e 100644 --- a/pyhon/printer.py +++ b/pyhon/printer.py @@ -29,33 +29,26 @@ def pretty_print( whitespace: str = " ", ) -> str: result = "" + space = whitespace * intend + if (isinstance(data, list) or isinstance(data, dict)) and key: + result += f"{space}{'- ' if is_list else ''}{key}:\n" + intend += 1 if isinstance(data, list): - if key: - result += f"{whitespace * intend}{'- ' if is_list else ''}{key}:\n" - intend += 1 for i, value in enumerate(data): result += pretty_print( value, intend=intend, is_list=True, whitespace=whitespace ) elif isinstance(data, dict): - if key: - result += f"{whitespace * intend}{'- ' if is_list else ''}{key}:\n" - intend += 1 for i, (key, value) in enumerate(sorted(data.items())): - if is_list and not i: - result += pretty_print( - value, key=key, intend=intend, is_list=True, whitespace=whitespace - ) - elif is_list: - result += pretty_print( - value, key=key, intend=intend + 1, whitespace=whitespace - ) - else: - result += pretty_print( - value, key=key, intend=intend, whitespace=whitespace - ) + result += pretty_print( + value, + key=key, + intend=intend + (is_list if i else 0), + is_list=is_list and not i, + whitespace=whitespace, + ) else: - result += f"{whitespace * intend}{'- ' if is_list else ''}{key}{': ' if key else ''}{data}\n" + result += f"{space}{'- ' if is_list else ''}{key}{': ' if key else ''}{data}\n" return result diff --git a/pyhon/rules.py b/pyhon/rules.py index eb580e1..5dadad7 100644 --- a/pyhon/rules.py +++ b/pyhon/rules.py @@ -3,6 +3,7 @@ from typing import List, Dict, TYPE_CHECKING, Any, Optional from pyhon.parameter.enum import HonParameterEnum from pyhon.parameter.range import HonParameterRange +from pyhon.typedefs import Parameter if TYPE_CHECKING: from pyhon.commands import HonCommand @@ -83,28 +84,42 @@ class HonRuleSet: for rule in rules: self._rules.setdefault(key, []).append(rule) + def _extra_rules_matches(self, rule: HonRule) -> bool: + if rule.extras: + for key, value in rule.extras.items(): + if not self._command.parameters.get(key): + return False + if str(self._command.parameters.get(key)) != str(value): + return False + return True + + def _apply_fixed(self, param: Parameter, value: str | float) -> None: + if isinstance(param, HonParameterEnum) and set(param.values) != {str(value)}: + param.values = [str(value)] + param.value = str(value) + elif isinstance(param, HonParameterRange): + param.value = float(value) + return + param.value = str(value) + + def _apply_enum(self, param: Parameter, rule: HonRule) -> None: + if not isinstance(param, HonParameterEnum): + return + if enum_values := rule.param_data.get("enumValues"): + param.values = enum_values.split("|") + if default_value := rule.param_data.get("defaultValue"): + param.value = default_value + def _add_trigger(self, parameter: "HonParameter", data: HonRule) -> None: def apply(rule: HonRule) -> None: - if rule.extras is not None: - for key, value in rule.extras.items(): - if str(self._command.parameters.get(key)) != str(value): - return - if param := self._command.parameters.get(rule.param_key): - if value := rule.param_data.get("fixedValue", ""): - if isinstance(param, HonParameterEnum) and set(param.values) != { - str(value) - }: - param.values = [str(value)] - elif isinstance(param, HonParameterRange): - param.value = float(value) - return - param.value = str(value) - elif rule.param_data.get("typology") == "enum": - if isinstance(param, HonParameterEnum): - if enum_values := rule.param_data.get("enumValues"): - param.values = enum_values.split("|") - if default_value := rule.param_data.get("defaultValue"): - param.value = default_value + if not self._extra_rules_matches(rule): + return + if not (param := self._command.parameters.get(rule.param_key)): + return + if fixed_value := rule.param_data.get("fixedValue", ""): + self._apply_fixed(param, fixed_value) + elif rule.param_data.get("typology") == "enum": + self._apply_enum(param, rule) parameter.add_trigger(data.trigger_value, apply, data)