add diagnose property for devices
This commit is contained in:
		
							
								
								
									
										83
									
								
								pyhon/__main__.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							
							
						
						
									
										83
									
								
								pyhon/__main__.py
									
									
									
									
									
										
										
										Executable file → Normal file
									
								
							@@ -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():
 | 
			
		||||
 
 | 
			
		||||
@@ -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")
 | 
			
		||||
 
 | 
			
		||||
@@ -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(
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										63
									
								
								pyhon/helper.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										63
									
								
								pyhon/helper.py
									
									
									
									
									
										Normal file
									
								
							@@ -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
 | 
			
		||||
		Reference in New Issue
	
	Block a user