From 993a4c1d793a07d0159abaa4c096f6b07f081e02 Mon Sep 17 00:00:00 2001 From: Andre Basche Date: Sat, 4 Mar 2023 21:27:10 +0100 Subject: [PATCH] Improve cmd tool, write README --- README.md | 44 +++++++++++++++++++++++++++++++++++++++++++- pyhon/__main__.py | 46 +++++++++++++++++++++++++++++++--------------- pyhon/api.py | 1 + pyhon/device.py | 6 +++--- setup.py | 4 ++-- 5 files changed, 80 insertions(+), 21 deletions(-) diff --git a/README.md b/README.md index fdb991f..81d139c 100644 --- a/README.md +++ b/README.md @@ -1 +1,43 @@ -# pyhOn \ No newline at end of file +**This python package is unofficial and is not related in any way to Haier. It was developed by reversed engineered requests and can stop working at anytime!** + +# pyhOn +Control your Haier appliances with python! +### Quick overview +To see the available options of the appliances from your Haier Account, use the commandline-tool `pyhOn` +```commandline +$ pyhOn --user example@mail.com --password pass123 +========== Waschmaschine ========== +commands: + pauseProgram: pauseProgram command + resumeProgram: resumeProgram command + startProgram: startProgram command + stopProgram: stopProgram command +data: + actualWeight: 0 + airWashTempLevel: 0 + airWashTime: 0 + antiAllergyStatus: 0 +... +``` + +## Python-API +### List devices +```python +import asyncio +from pyhon import HonConnection + +async def devices_example(): + async with HonConnection(USER, PASSWORD) as hon: + for device in hon.devices: + print(device.nick_name) + +asyncio.run(devices_example()) +``` + +### Execute a command +```python +async with HonConnection(USER, PASSWORD) as hon: + washing_machine = hon[0] + pause_command = washing_machine.commands["pauseProgram"] + await pause_command.send() +``` diff --git a/pyhon/__main__.py b/pyhon/__main__.py index f0e5733..8e6c310 100755 --- a/pyhon/__main__.py +++ b/pyhon/__main__.py @@ -18,30 +18,46 @@ _LOGGER = logging.getLogger(__name__) def get_arguments(): """Get parsed arguments.""" - parser = argparse.ArgumentParser(description="hOn: Command Line Utility") - parser.add_argument("-u", "--user", help="user of haier hOn account") - parser.add_argument("-p", "--password", help="password of haier hOn account") + parser = argparse.ArgumentParser(description="pyhOn: Command Line Utility") + parser.add_argument("-u", "--user", help="user for haier hOn account") + parser.add_argument("-p", "--password", help="password for haier hOn account") return vars(parser.parse_args()) +# yaml.dump() would be done the same, but needs an additional import... +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}") + + async def main(): args = get_arguments() if not (user := args["user"]): - user = input("User of hOn account: ") + user = input("User for hOn account: ") if not (password := args["password"]): - password = getpass("Password of hOn account: ") + password = getpass("Password for hOn account: ") async with HonConnection(user, password) as hon: - await hon.setup() for device in hon.devices: - print(10 * "=", device.nick_name, 10 * "=") - print(10 * "-", "attributes", 10 * "-") - pprint(device.attributes) - print(10 * "-", "statistics", 10 * "-") - pprint(device.statistics) - print(10 * "-", "commands", 10 * "-") - pprint(device.parameters) - print(10 * "-", "settings", 10 * "-") - pprint(device.settings) + print("=" * 10, device.nick_name, "=" * 10) + pretty_print({"commands": device.commands}) + pretty_print({"data": device.data}) def start(): diff --git a/pyhon/api.py b/pyhon/api.py index d018c67..7d147b2 100644 --- a/pyhon/api.py +++ b/pyhon/api.py @@ -26,6 +26,7 @@ class HonConnection: async def __aenter__(self): self._session = aiohttp.ClientSession() + await self.setup() return self async def __aexit__(self, exc_type, exc_val, exc_tb): diff --git a/pyhon/device.py b/pyhon/device.py index c04bf79..f36b04c 100644 --- a/pyhon/device.py +++ b/pyhon/device.py @@ -9,7 +9,7 @@ class HonDevice: self._commands = {} self._statistics = {} - self._attributs = {} + self._attributes = {} @property def appliance_id(self): @@ -117,7 +117,7 @@ class HonDevice: @property def attributes(self): - return self._attributs + return self._attributes @property def statistics(self): @@ -159,7 +159,7 @@ class HonDevice: async def load_attributes(self): data = await self._connector.load_attributes(self) for name, values in data.get("shadow").get("parameters").items(): - self._attributs[name] = values["parNewVal"] + self._attributes[name] = values["parNewVal"] async def load_statistics(self): self._statistics = await self._connector.load_statistics(self) diff --git a/setup.py b/setup.py index c147ba3..d85b2ae 100644 --- a/setup.py +++ b/setup.py @@ -7,12 +7,12 @@ with open("README.md", "r") as f: setup( name="pyhOn", - version="0.0.14", + version="0.2.0", author="Andre Basche", description="Control hOn devices with python", long_description=long_description, long_description_content_type='text/markdown', - url="https://github.com/Andre0512/pyhon", + url="https://github.com/Andre0512/pyh0n", license="MIT", platforms="any", packages=find_packages(),