From 46e6a85e849496739a1b179778a5802afb860b38 Mon Sep 17 00:00:00 2001 From: Andre Basche Date: Tue, 11 Apr 2023 22:14:36 +0200 Subject: [PATCH] add diagnose property for devices --- pyhon/__main__.py | 83 +++++++++---------------------------- pyhon/appliance.py | 13 ++++++ pyhon/connection/handler.py | 8 +++- pyhon/helper.py | 63 ++++++++++++++++++++++++++++ setup.py | 2 +- 5 files changed, 103 insertions(+), 66 deletions(-) mode change 100755 => 100644 pyhon/__main__.py create mode 100644 pyhon/helper.py diff --git a/pyhon/__main__.py b/pyhon/__main__.py old mode 100755 new mode 100644 index 38e6958..ed28866 --- a/pyhon/__main__.py +++ b/pyhon/__main__.py @@ -10,7 +10,7 @@ from pathlib import Path if __name__ == "__main__": sys.path.insert(0, str(Path(__file__).parent.parent)) -from pyhon import Hon, HonAPI +from pyhon import Hon, HonAPI, helper _LOGGER = logging.getLogger(__name__) @@ -34,61 +34,6 @@ def get_arguments(): return vars(parser.parse_args()) -# yaml.dump() would be done the same, but needs an additional dependency... -def pretty_print(data, key="", intend=0, is_list=False): - if type(data) is list: - if key: - print(f"{' ' * intend}{'- ' if is_list else ''}{key}:") - intend += 1 - for i, value in enumerate(data): - pretty_print(value, intend=intend, is_list=True) - elif type(data) is dict: - if key: - print(f"{' ' * intend}{'- ' if is_list else ''}{key}:") - intend += 1 - for i, (key, value) in enumerate(sorted(data.items())): - if is_list and not i: - pretty_print(value, key=key, intend=intend, is_list=True) - elif is_list: - pretty_print(value, key=key, intend=intend + 1) - else: - pretty_print(value, key=key, intend=intend) - else: - print( - f"{' ' * intend}{'- ' if is_list else ''}{key}{': ' if key else ''}{data}" - ) - - -def key_print(data, key="", start=True): - if type(data) is list: - for i, value in enumerate(data): - key_print(value, key=f"{key}.{i}", start=False) - elif type(data) is dict: - for k, value in sorted(data.items()): - key_print(value, key=k if start else f"{key}.{k}", start=False) - else: - print(f"{key}: {data}") - - -def create_command(commands, concat=False): - result = {} - for name, command in commands.items(): - if not concat: - result[name] = {} - for parameter, data in command.parameters.items(): - if data.typology == "enum": - value = data.values - elif data.typology == "range": - value = {"min": data.min, "max": data.max, "step": data.step} - else: - continue - if not concat: - result[name][parameter] = value - else: - result[f"{name}.{parameter}"] = value - return result - - async def translate(language, json_output=False): async with HonAPI(anonymous=True) as hon: keys = await hon.translation_keys(language) @@ -102,7 +47,7 @@ async def translate(language, json_output=False): .replace("\\r", "") ) keys = json.loads(clean_keys) - pretty_print(keys) + print(helper.pretty_print(keys)) async def main(): @@ -120,13 +65,25 @@ async def main(): if args.get("keys"): data = device.data.copy() attr = "get" if args.get("all") else "pop" - key_print(data["attributes"].__getattribute__(attr)("parameters")) - key_print(data.__getattribute__(attr)("appliance")) - key_print(data) - pretty_print(create_command(device.commands, concat=True)) + print( + helper.key_print( + data["attributes"].__getattribute__(attr)("parameters") + ) + ) + print(helper.key_print(data.__getattribute__(attr)("appliance"))) + print(helper.key_print(data)) + print( + helper.pretty_print( + helper.create_command(device.commands, concat=True) + ) + ) else: - pretty_print({"data": device.data}) - pretty_print({"settings": create_command(device.commands)}) + print(helper.pretty_print({"data": device.data})) + print( + helper.pretty_print( + {"settings": helper.create_command(device.commands)} + ) + ) def start(): diff --git a/pyhon/appliance.py b/pyhon/appliance.py index 5ce7db3..21d39c6 100644 --- a/pyhon/appliance.py +++ b/pyhon/appliance.py @@ -1,6 +1,7 @@ import importlib from contextlib import suppress +from pyhon import helper from pyhon.commands import HonCommand from pyhon.parameter import HonParameterFixed @@ -172,3 +173,15 @@ class HonAppliance: if self._extra: return self._extra.data(result) return result + + @property + def diagnose(self): + data = self.data.copy() + for sensible in ["PK", "SK", "serialNumber", "code"]: + data["appliance"].pop(sensible, None) + result = helper.pretty_print({"data": self.data}, whitespace="\u200B \u200B ") + result += helper.pretty_print( + {"commands": helper.create_command(self.commands)}, + whitespace="\u200B \u200B ", + ) + return result.replace(self.mac_address, "12-34-56-78-90-ab") diff --git a/pyhon/connection/handler.py b/pyhon/connection/handler.py index 8895a36..dc18082 100644 --- a/pyhon/connection/handler.py +++ b/pyhon/connection/handler.py @@ -84,7 +84,9 @@ class HonConnectionHandler(HonBaseConnectionHandler): if response.status in [401, 403] and loop == 0: _LOGGER.info("Try refreshing token...") await self._auth.refresh() - async with self._intercept(method, *args, loop=loop + 1, **kwargs) as result: + async with self._intercept( + method, *args, loop=loop + 1, **kwargs + ) as result: yield result elif response.status in [401, 403] and loop == 1: _LOGGER.warning( @@ -94,7 +96,9 @@ class HonConnectionHandler(HonBaseConnectionHandler): await response.text(), ) await self.create() - async with self._intercept(method, *args, loop=loop + 1, **kwargs) as result: + async with self._intercept( + method, *args, loop=loop + 1, **kwargs + ) as result: yield result elif loop >= 2: _LOGGER.error( diff --git a/pyhon/helper.py b/pyhon/helper.py new file mode 100644 index 0000000..d126b91 --- /dev/null +++ b/pyhon/helper.py @@ -0,0 +1,63 @@ +def key_print(data, key="", start=True): + result = "" + if isinstance(data, list): + for i, value in enumerate(data): + result += key_print(value, key=f"{key}.{i}", start=False) + elif isinstance(data, dict): + for k, value in sorted(data.items()): + result += key_print(value, key=k if start else f"{key}.{k}", start=False) + else: + result += f"{key}: {data}\n" + return result + + +# yaml.dump() would be done the same, but needs an additional dependency... +def pretty_print(data, key="", intend=0, is_list=False, whitespace=" "): + result = "" + 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 + ) + else: + result += f"{whitespace * intend}{'- ' if is_list else ''}{key}{': ' if key else ''}{data}\n" + return result + + +def create_command(commands, concat=False): + result = {} + for name, command in commands.items(): + if not concat: + result[name] = {} + for parameter, data in command.parameters.items(): + if data.typology == "enum": + value = data.values + elif data.typology == "range": + value = {"min": data.min, "max": data.max, "step": data.step} + else: + continue + if not concat: + result[name][parameter] = value + else: + result[f"{name}.{parameter}"] = value + return result diff --git a/setup.py b/setup.py index 2ef3b45..71fb903 100644 --- a/setup.py +++ b/setup.py @@ -7,7 +7,7 @@ with open("README.md", "r") as f: setup( name="pyhOn", - version="0.6.4", + version="0.7.0", author="Andre Basche", description="Control hOn devices with python", long_description=long_description,