From dd61b24eedeaf302513fa28cd66e1c98688abfe7 Mon Sep 17 00:00:00 2001 From: Andre Basche Date: Sat, 6 May 2023 20:00:13 +0200 Subject: [PATCH] Improve output --- pyhon/__main__.py | 7 +----- pyhon/appliance.py | 48 +++++++++++++++++++++++--------------- pyhon/commands.py | 45 ++++++++++++++++++++++++----------- pyhon/parameter/program.py | 2 +- setup.py | 2 +- 5 files changed, 63 insertions(+), 41 deletions(-) diff --git a/pyhon/__main__.py b/pyhon/__main__.py index ed28866..41ffdf6 100755 --- a/pyhon/__main__.py +++ b/pyhon/__main__.py @@ -78,12 +78,7 @@ async def main(): ) ) else: - print(helper.pretty_print({"data": device.data})) - print( - helper.pretty_print( - {"settings": helper.create_command(device.commands)} - ) - ) + print(device.diagnose(" ")) def start(): diff --git a/pyhon/appliance.py b/pyhon/appliance.py index 22b95a2..0bc2814 100644 --- a/pyhon/appliance.py +++ b/pyhon/appliance.py @@ -4,7 +4,7 @@ from contextlib import suppress from typing import Optional, Dict, Any from typing import TYPE_CHECKING -from pyhon import helper +from pyhon import helper, exceptions from pyhon.commands import HonCommand from pyhon.parameter.base import HonParameter from pyhon.parameter.fixed import HonParameterFixed @@ -29,7 +29,7 @@ class HonAppliance: self._statistics: Dict = {} self._attributes: Dict = {} self._zone: int = zone - self._additional_data = {} + self._additional_data: Dict[str, Any] = {} try: self._extra = importlib.import_module( @@ -119,8 +119,14 @@ class HonAppliance: def zone(self) -> int: return self._zone + @property + def api(self) -> "HonAPI": + if self._api is None: + raise exceptions.NoAuthenticationException + return self._api + async def _recover_last_command_states(self): - command_history = await self._api.command_history(self) + command_history = await self.api.command_history(self) for name, command in self._commands.items(): last = next( ( @@ -170,7 +176,6 @@ class HonAppliance: HonCommand( command, data, - self._api, self, category_name=category, categories=categories, @@ -178,35 +183,33 @@ class HonAppliance: ] else: commands += self._get_categories(command, data) + elif category: + self._additional_data.setdefault(command, {})[category] = data else: self._additional_data[command] = data return commands async def load_commands(self): - raw = await self._api.load_commands(self) + raw = await self.api.load_commands(self) self._appliance_model = raw.pop("applianceModel") raw.pop("dictionaryId") self._commands = self._get_commands(raw) await self._recover_last_command_states() async def load_attributes(self): - self._attributes = await self._api.load_attributes(self) + self._attributes = await self.api.load_attributes(self) for name, values in self._attributes.pop("shadow").get("parameters").items(): self._attributes.setdefault("parameters", {})[name] = values["parNewVal"] async def load_statistics(self): - self._statistics = await self._api.load_statistics(self) + self._statistics = await self.api.load_statistics(self) async def update(self): await self.load_attributes() @property - def parameters(self): - result = {} - for name, command in self._commands.items(): - for key, parameter in command.parameters.items(): - result.setdefault(name, {})[key] = parameter.value - return result + def command_parameters(self): + return {n: c.parameter_value for n, c in self._commands.items()} @property def settings(self): @@ -226,20 +229,27 @@ class HonAppliance: "appliance": self.info, "statistics": self.statistics, "additional_data": self._additional_data, - **self.parameters, + **self.command_parameters, } if self._extra: return self._extra.data(result) return result - @property - def diagnose(self): - data = self.data.copy() + def diagnose(self, whitespace="\u200B \u200B "): + data = { + "attributes": self.attributes.copy(), + "appliance": self.info, + "additional_data": self._additional_data, + } + data |= {n: c.parameter_groups for n, c in self._commands.items()} + extra = {n: c.data for n, c in self._commands.items() if c.data} + if extra: + data |= {"extra_command_data": extra} for sensible in ["PK", "SK", "serialNumber", "code", "coords"]: data["appliance"].pop(sensible, None) - result = helper.pretty_print({"data": self.data}, whitespace="\u200B \u200B ") + result = helper.pretty_print({"data": data}, whitespace=whitespace) result += helper.pretty_print( {"commands": helper.create_command(self.commands)}, - whitespace="\u200B \u200B ", + whitespace=whitespace, ) return result.replace(self.mac_address, "xx-xx-xx-xx-xx-xx") diff --git a/pyhon/commands.py b/pyhon/commands.py index 180a4bf..9ed5d30 100644 --- a/pyhon/commands.py +++ b/pyhon/commands.py @@ -1,4 +1,4 @@ -from typing import Optional, Dict, Any, List, TYPE_CHECKING +from typing import Optional, Dict, Any, List, TYPE_CHECKING, Union from pyhon.parameter.base import HonParameter from pyhon.parameter.enum import HonParameterEnum @@ -16,12 +16,11 @@ class HonCommand: self, name: str, attributes: Dict[str, Any], - api: "HonAPI", appliance: "HonAppliance", categories: Optional[Dict[str, "HonCommand"]] = None, category_name: str = "", ): - self._api: HonAPI = api + self._api: HonAPI = appliance.api self._appliance: "HonAppliance" = appliance self._name: str = name self._categories: Optional[Dict[str, "HonCommand"]] = categories @@ -29,7 +28,7 @@ class HonCommand: self._description: str = attributes.pop("description", "") self._protocol_type: str = attributes.pop("protocolType", "") self._parameters: Dict[str, HonParameter] = {} - self._data = {} + self._data: Dict[str, Any] = {} self._load_parameters(attributes) def __repr__(self) -> str: @@ -47,6 +46,17 @@ class HonCommand: def parameters(self) -> Dict[str, HonParameter]: return self._parameters + @property + def parameter_groups(self) -> Dict[str, Dict[str, Union[str, float]]]: + result: Dict[str, Dict[str, Union[str, float]]] = {} + for name, parameter in self._parameters.items(): + result.setdefault(parameter.group, {})[name] = parameter.value + return result + + @property + def parameter_value(self) -> Dict[str, Union[str, float]]: + return {n: p.value for n, p in self._parameters.items()} + def _load_parameters(self, attributes): for key, items in attributes.items(): for name, data in items.items(): @@ -67,16 +77,13 @@ class HonCommand: return if self._category_name: if not self._categories: - self._parameters["program"] = HonParameterProgram("program", self, name) - - def _parameters_by_group(self, group): - return { - name: v.value for name, v in self._parameters.items() if v.group == group - } + self._parameters["program"] = HonParameterProgram( + "program", self, "custom" + ) async def send(self) -> bool: - params = self._parameters_by_group("parameters") - ancillary_params = self._parameters_by_group("ancillary_parameters") + params = self.parameter_groups["parameters"] + ancillary_params = self.parameter_groups["ancillary_parameters"] return await self._api.send_command( self._appliance, self._name, params, ancillary_params ) @@ -101,12 +108,22 @@ class HonCommand: {param for cmd in self.categories.values() for param in cmd.parameters} ) + @staticmethod + def _more_options(first: HonParameter, second: HonParameter): + if isinstance(first, HonParameterFixed) and not isinstance( + second, HonParameterFixed + ): + return second + if len(second.values) > len(first.values): + return second + return first + @property def settings(self) -> Dict[str, HonParameter]: - result = {} + result: Dict[str, HonParameter] = {} for command in self.categories.values(): for name, parameter in command.parameters.items(): if name in result: - continue + result[name] = self._more_options(result[name], parameter) result[name] = parameter return result diff --git a/pyhon/parameter/program.py b/pyhon/parameter/program.py index 37b807d..32a3c79 100644 --- a/pyhon/parameter/program.py +++ b/pyhon/parameter/program.py @@ -23,7 +23,7 @@ class HonParameterProgram(HonParameterEnum): @value.setter def value(self, value: str) -> None: if value in self.values: - self._command.program = value + self._command.category = value else: raise ValueError(f"Allowed values {self.values}") diff --git a/setup.py b/setup.py index f665f08..4d35641 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ with open("README.md", "r") as f: setup( name="pyhOn", - version="0.10.0b0", + version="0.10.0", author="Andre Basche", description="Control hOn devices with python", long_description=long_description,