Improve output

This commit is contained in:
Andre Basche 2023-05-06 20:00:13 +02:00
parent ea8f481b01
commit dd61b24eed
5 changed files with 63 additions and 41 deletions

View file

@ -78,12 +78,7 @@ async def main():
) )
) )
else: else:
print(helper.pretty_print({"data": device.data})) print(device.diagnose(" "))
print(
helper.pretty_print(
{"settings": helper.create_command(device.commands)}
)
)
def start(): def start():

View file

@ -4,7 +4,7 @@ from contextlib import suppress
from typing import Optional, Dict, Any from typing import Optional, Dict, Any
from typing import TYPE_CHECKING from typing import TYPE_CHECKING
from pyhon import helper from pyhon import helper, exceptions
from pyhon.commands import HonCommand from pyhon.commands import HonCommand
from pyhon.parameter.base import HonParameter from pyhon.parameter.base import HonParameter
from pyhon.parameter.fixed import HonParameterFixed from pyhon.parameter.fixed import HonParameterFixed
@ -29,7 +29,7 @@ class HonAppliance:
self._statistics: Dict = {} self._statistics: Dict = {}
self._attributes: Dict = {} self._attributes: Dict = {}
self._zone: int = zone self._zone: int = zone
self._additional_data = {} self._additional_data: Dict[str, Any] = {}
try: try:
self._extra = importlib.import_module( self._extra = importlib.import_module(
@ -119,8 +119,14 @@ class HonAppliance:
def zone(self) -> int: def zone(self) -> int:
return self._zone 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): 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(): for name, command in self._commands.items():
last = next( last = next(
( (
@ -170,7 +176,6 @@ class HonAppliance:
HonCommand( HonCommand(
command, command,
data, data,
self._api,
self, self,
category_name=category, category_name=category,
categories=categories, categories=categories,
@ -178,35 +183,33 @@ class HonAppliance:
] ]
else: else:
commands += self._get_categories(command, data) commands += self._get_categories(command, data)
elif category:
self._additional_data.setdefault(command, {})[category] = data
else: else:
self._additional_data[command] = data self._additional_data[command] = data
return commands return commands
async def load_commands(self): 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") self._appliance_model = raw.pop("applianceModel")
raw.pop("dictionaryId") raw.pop("dictionaryId")
self._commands = self._get_commands(raw) self._commands = self._get_commands(raw)
await self._recover_last_command_states() await self._recover_last_command_states()
async def load_attributes(self): 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(): for name, values in self._attributes.pop("shadow").get("parameters").items():
self._attributes.setdefault("parameters", {})[name] = values["parNewVal"] self._attributes.setdefault("parameters", {})[name] = values["parNewVal"]
async def load_statistics(self): 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): async def update(self):
await self.load_attributes() await self.load_attributes()
@property @property
def parameters(self): def command_parameters(self):
result = {} return {n: c.parameter_value for n, c in self._commands.items()}
for name, command in self._commands.items():
for key, parameter in command.parameters.items():
result.setdefault(name, {})[key] = parameter.value
return result
@property @property
def settings(self): def settings(self):
@ -226,20 +229,27 @@ class HonAppliance:
"appliance": self.info, "appliance": self.info,
"statistics": self.statistics, "statistics": self.statistics,
"additional_data": self._additional_data, "additional_data": self._additional_data,
**self.parameters, **self.command_parameters,
} }
if self._extra: if self._extra:
return self._extra.data(result) return self._extra.data(result)
return result return result
@property def diagnose(self, whitespace="\u200B \u200B "):
def diagnose(self): data = {
data = self.data.copy() "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"]: for sensible in ["PK", "SK", "serialNumber", "code", "coords"]:
data["appliance"].pop(sensible, None) 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( result += helper.pretty_print(
{"commands": helper.create_command(self.commands)}, {"commands": helper.create_command(self.commands)},
whitespace="\u200B \u200B ", whitespace=whitespace,
) )
return result.replace(self.mac_address, "xx-xx-xx-xx-xx-xx") return result.replace(self.mac_address, "xx-xx-xx-xx-xx-xx")

View file

@ -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.base import HonParameter
from pyhon.parameter.enum import HonParameterEnum from pyhon.parameter.enum import HonParameterEnum
@ -16,12 +16,11 @@ class HonCommand:
self, self,
name: str, name: str,
attributes: Dict[str, Any], attributes: Dict[str, Any],
api: "HonAPI",
appliance: "HonAppliance", appliance: "HonAppliance",
categories: Optional[Dict[str, "HonCommand"]] = None, categories: Optional[Dict[str, "HonCommand"]] = None,
category_name: str = "", category_name: str = "",
): ):
self._api: HonAPI = api self._api: HonAPI = appliance.api
self._appliance: "HonAppliance" = appliance self._appliance: "HonAppliance" = appliance
self._name: str = name self._name: str = name
self._categories: Optional[Dict[str, "HonCommand"]] = categories self._categories: Optional[Dict[str, "HonCommand"]] = categories
@ -29,7 +28,7 @@ class HonCommand:
self._description: str = attributes.pop("description", "") self._description: str = attributes.pop("description", "")
self._protocol_type: str = attributes.pop("protocolType", "") self._protocol_type: str = attributes.pop("protocolType", "")
self._parameters: Dict[str, HonParameter] = {} self._parameters: Dict[str, HonParameter] = {}
self._data = {} self._data: Dict[str, Any] = {}
self._load_parameters(attributes) self._load_parameters(attributes)
def __repr__(self) -> str: def __repr__(self) -> str:
@ -47,6 +46,17 @@ class HonCommand:
def parameters(self) -> Dict[str, HonParameter]: def parameters(self) -> Dict[str, HonParameter]:
return self._parameters 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): def _load_parameters(self, attributes):
for key, items in attributes.items(): for key, items in attributes.items():
for name, data in items.items(): for name, data in items.items():
@ -67,16 +77,13 @@ class HonCommand:
return return
if self._category_name: if self._category_name:
if not self._categories: if not self._categories:
self._parameters["program"] = HonParameterProgram("program", self, name) self._parameters["program"] = HonParameterProgram(
"program", self, "custom"
def _parameters_by_group(self, group): )
return {
name: v.value for name, v in self._parameters.items() if v.group == group
}
async def send(self) -> bool: async def send(self) -> bool:
params = self._parameters_by_group("parameters") params = self.parameter_groups["parameters"]
ancillary_params = self._parameters_by_group("ancillary_parameters") ancillary_params = self.parameter_groups["ancillary_parameters"]
return await self._api.send_command( return await self._api.send_command(
self._appliance, self._name, params, ancillary_params 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} {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 @property
def settings(self) -> Dict[str, HonParameter]: def settings(self) -> Dict[str, HonParameter]:
result = {} result: Dict[str, HonParameter] = {}
for command in self.categories.values(): for command in self.categories.values():
for name, parameter in command.parameters.items(): for name, parameter in command.parameters.items():
if name in result: if name in result:
continue result[name] = self._more_options(result[name], parameter)
result[name] = parameter result[name] = parameter
return result return result

View file

@ -23,7 +23,7 @@ class HonParameterProgram(HonParameterEnum):
@value.setter @value.setter
def value(self, value: str) -> None: def value(self, value: str) -> None:
if value in self.values: if value in self.values:
self._command.program = value self._command.category = value
else: else:
raise ValueError(f"Allowed values {self.values}") raise ValueError(f"Allowed values {self.values}")

View file

@ -7,7 +7,7 @@ with open("README.md", "r") as f:
setup( setup(
name="pyhOn", name="pyhOn",
version="0.10.0b0", version="0.10.0",
author="Andre Basche", author="Andre Basche",
description="Control hOn devices with python", description="Control hOn devices with python",
long_description=long_description, long_description=long_description,