Improve output
This commit is contained in:
		@@ -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():
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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}")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										2
									
								
								setup.py
									
									
									
									
									
								
							
							
						
						
									
										2
									
								
								setup.py
									
									
									
									
									
								
							@@ -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,
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user