Refactor api access
This commit is contained in:
		@@ -1 +1,2 @@
 | 
				
			|||||||
from .connection.api import HonAPI
 | 
					from .connection.api import HonAPI
 | 
				
			||||||
 | 
					from hon import Hon
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@ from pprint import pprint
 | 
				
			|||||||
if __name__ == "__main__":
 | 
					if __name__ == "__main__":
 | 
				
			||||||
    sys.path.insert(0, str(Path(__file__).parent.parent))
 | 
					    sys.path.insert(0, str(Path(__file__).parent.parent))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import HonAPI
 | 
					from pyhon import Hon, HonAPI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger(__name__)
 | 
					_LOGGER = logging.getLogger(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -104,8 +104,8 @@ async def main():
 | 
				
			|||||||
        user = input("User for hOn account: ")
 | 
					        user = input("User for hOn account: ")
 | 
				
			||||||
    if not (password := args["password"]):
 | 
					    if not (password := args["password"]):
 | 
				
			||||||
        password = getpass("Password for hOn account: ")
 | 
					        password = getpass("Password for hOn account: ")
 | 
				
			||||||
    async with HonAPI(user, password) as hon:
 | 
					    async with Hon(user, password) as hon:
 | 
				
			||||||
        for device in hon.devices:
 | 
					        for device in hon.appliances:
 | 
				
			||||||
            print("=" * 10, device.appliance_type, "-", device.nick_name, "=" * 10)
 | 
					            print("=" * 10, device.appliance_type, "-", device.nick_name, "=" * 10)
 | 
				
			||||||
            if args.get("keys"):
 | 
					            if args.get("keys"):
 | 
				
			||||||
                data = device.data.copy()
 | 
					                data = device.data.copy()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -6,11 +6,11 @@ from pyhon.parameter import HonParameterFixed
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class HonAppliance:
 | 
					class HonAppliance:
 | 
				
			||||||
    def __init__(self, connector, appliance):
 | 
					    def __init__(self, api, info):
 | 
				
			||||||
        if attributes := appliance.get("attributes"):
 | 
					        if attributes := info.get("attributes"):
 | 
				
			||||||
            appliance["attributes"] = {v["parName"]: v["parValue"] for v in attributes}
 | 
					            info["attributes"] = {v["parName"]: v["parValue"] for v in attributes}
 | 
				
			||||||
        self._appliance = appliance
 | 
					        self._info = info
 | 
				
			||||||
        self._connector = connector
 | 
					        self._api = api
 | 
				
			||||||
        self._appliance_model = {}
 | 
					        self._appliance_model = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self._commands = {}
 | 
					        self._commands = {}
 | 
				
			||||||
@@ -36,7 +36,7 @@ class HonAppliance:
 | 
				
			|||||||
                return self.data[item]
 | 
					                return self.data[item]
 | 
				
			||||||
            if item in self.attributes["parameters"]:
 | 
					            if item in self.attributes["parameters"]:
 | 
				
			||||||
                return self.attributes["parameters"].get(item)
 | 
					                return self.attributes["parameters"].get(item)
 | 
				
			||||||
            return self.appliance[item]
 | 
					            return self.info[item]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get(self, item, default=None):
 | 
					    def get(self, item, default=None):
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
@@ -46,23 +46,23 @@ class HonAppliance:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def appliance_model_id(self):
 | 
					    def appliance_model_id(self):
 | 
				
			||||||
        return self._appliance.get("applianceModelId")
 | 
					        return self._info.get("applianceModelId")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def appliance_type(self):
 | 
					    def appliance_type(self):
 | 
				
			||||||
        return self._appliance.get("applianceTypeName")
 | 
					        return self._info.get("applianceTypeName")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def mac_address(self):
 | 
					    def mac_address(self):
 | 
				
			||||||
        return self._appliance.get("macAddress")
 | 
					        return self._info.get("macAddress")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def model_name(self):
 | 
					    def model_name(self):
 | 
				
			||||||
        return self._appliance.get("modelName")
 | 
					        return self._info.get("modelName")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def nick_name(self):
 | 
					    def nick_name(self):
 | 
				
			||||||
        return self._appliance.get("nickName")
 | 
					        return self._info.get("nickName")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def commands_options(self):
 | 
					    def commands_options(self):
 | 
				
			||||||
@@ -81,11 +81,11 @@ class HonAppliance:
 | 
				
			|||||||
        return self._statistics
 | 
					        return self._statistics
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    @property
 | 
				
			||||||
    def appliance(self):
 | 
					    def info(self):
 | 
				
			||||||
        return self._appliance
 | 
					        return self._info
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _recover_last_command_states(self, commands):
 | 
					    async def _recover_last_command_states(self, commands):
 | 
				
			||||||
        command_history = await self._connector.command_history(self)
 | 
					        command_history = await self._api.command_history(self)
 | 
				
			||||||
        for name, command in commands.items():
 | 
					        for name, command in commands.items():
 | 
				
			||||||
            last = next((index for (index, d) in enumerate(command_history) if d.get("command", {}).get("commandName") == name), None)
 | 
					            last = next((index for (index, d) in enumerate(command_history) if d.get("command", {}).get("commandName") == name), None)
 | 
				
			||||||
            if last is None:
 | 
					            if last is None:
 | 
				
			||||||
@@ -100,19 +100,19 @@ class HonAppliance:
 | 
				
			|||||||
                        data.value = parameters.get(key)
 | 
					                        data.value = parameters.get(key)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def load_commands(self):
 | 
					    async def load_commands(self):
 | 
				
			||||||
        raw = await self._connector.load_commands(self)
 | 
					        raw = await self._api.load_commands(self)
 | 
				
			||||||
        self._appliance_model = raw.pop("applianceModel")
 | 
					        self._appliance_model = raw.pop("applianceModel")
 | 
				
			||||||
        for item in ["settings", "options", "dictionaryId"]:
 | 
					        for item in ["settings", "options", "dictionaryId"]:
 | 
				
			||||||
            raw.pop(item)
 | 
					            raw.pop(item)
 | 
				
			||||||
        commands = {}
 | 
					        commands = {}
 | 
				
			||||||
        for command, attr in raw.items():
 | 
					        for command, attr in raw.items():
 | 
				
			||||||
            if "parameters" in attr:
 | 
					            if "parameters" in attr:
 | 
				
			||||||
                commands[command] = HonCommand(command, attr, self._connector, self)
 | 
					                commands[command] = HonCommand(command, attr, self._api, self)
 | 
				
			||||||
            elif "parameters" in attr[list(attr)[0]]:
 | 
					            elif "parameters" in attr[list(attr)[0]]:
 | 
				
			||||||
                multi = {}
 | 
					                multi = {}
 | 
				
			||||||
                for program, attr2 in attr.items():
 | 
					                for program, attr2 in attr.items():
 | 
				
			||||||
                    program = program.split(".")[-1].lower()
 | 
					                    program = program.split(".")[-1].lower()
 | 
				
			||||||
                    cmd = HonCommand(command, attr2, self._connector, self, multi=multi, program=program)
 | 
					                    cmd = HonCommand(command, attr2, self._api, self, multi=multi, program=program)
 | 
				
			||||||
                    multi[program] = cmd
 | 
					                    multi[program] = cmd
 | 
				
			||||||
                    commands[command] = cmd
 | 
					                    commands[command] = cmd
 | 
				
			||||||
        self._commands = commands
 | 
					        self._commands = commands
 | 
				
			||||||
@@ -137,19 +137,19 @@ class HonAppliance:
 | 
				
			|||||||
        return result
 | 
					        return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def load_attributes(self):
 | 
					    async def load_attributes(self):
 | 
				
			||||||
        self._attributes = await self._connector.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._connector.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 data(self):
 | 
					    def data(self):
 | 
				
			||||||
        result = {"attributes": self.attributes, "appliance": self.appliance, "statistics": self.statistics,
 | 
					        result = {"attributes": self.attributes, "appliance": self.info, "statistics": self.statistics,
 | 
				
			||||||
                  **self.parameters}
 | 
					                  **self.parameters}
 | 
				
			||||||
        if self._extra:
 | 
					        if self._extra:
 | 
				
			||||||
            return self._extra.data(result)
 | 
					            return self._extra.data(result)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,12 +1,10 @@
 | 
				
			|||||||
import asyncio
 | 
					 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
from datetime import datetime
 | 
					from datetime import datetime
 | 
				
			||||||
from typing import List
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
from pyhon import const
 | 
					from pyhon import const
 | 
				
			||||||
from pyhon.appliance import HonAppliance
 | 
					from pyhon.appliance import HonAppliance
 | 
				
			||||||
from pyhon.connection.connection import HonConnectionHandler, HonAnonymousConnectionHandler
 | 
					from pyhon.connection.handler import HonConnectionHandler, HonAnonymousConnectionHandler
 | 
				
			||||||
 | 
					
 | 
				
			||||||
_LOGGER = logging.getLogger()
 | 
					_LOGGER = logging.getLogger()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -16,53 +14,34 @@ class HonAPI:
 | 
				
			|||||||
        super().__init__()
 | 
					        super().__init__()
 | 
				
			||||||
        self._email = email
 | 
					        self._email = email
 | 
				
			||||||
        self._password = password
 | 
					        self._password = password
 | 
				
			||||||
        self._devices = []
 | 
					 | 
				
			||||||
        self._hon = None
 | 
					        self._hon = None
 | 
				
			||||||
        self._hon_anonymous = HonAnonymousConnectionHandler()
 | 
					        self._hon_anonymous = HonAnonymousConnectionHandler()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def __aenter__(self):
 | 
					    async def __aenter__(self):
 | 
				
			||||||
        self._hon = HonConnectionHandler(self._email, self._password)
 | 
					        return await self.create()
 | 
				
			||||||
        await self._hon.create()
 | 
					 | 
				
			||||||
        await self.setup()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def __aexit__(self, exc_type, exc_val, exc_tb):
 | 
					    async def __aexit__(self, exc_type, exc_val, exc_tb):
 | 
				
			||||||
        await self._hon.close()
 | 
					        await self._hon.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @property
 | 
					    async def create(self):
 | 
				
			||||||
    def devices(self) -> List[HonAppliance]:
 | 
					        self._hon = await HonConnectionHandler(self._email, self._password).create()
 | 
				
			||||||
        return self._devices
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def setup(self):
 | 
					    async def load_appliances(self):
 | 
				
			||||||
        async with self._hon.get(f"{const.API_URL}/commands/v1/appliance") as resp:
 | 
					        async with self._hon.get(f"{const.API_URL}/commands/v1/appliance") as resp:
 | 
				
			||||||
            try:
 | 
					            return await resp.json()
 | 
				
			||||||
                appliances = (await resp.json())["payload"]["appliances"]
 | 
					 | 
				
			||||||
                for appliance in appliances:
 | 
					 | 
				
			||||||
                    device = HonAppliance(self, appliance)
 | 
					 | 
				
			||||||
                    if device.mac_address is None:
 | 
					 | 
				
			||||||
                        continue
 | 
					 | 
				
			||||||
                    await asyncio.gather(*[
 | 
					 | 
				
			||||||
                        device.load_attributes(),
 | 
					 | 
				
			||||||
                        device.load_commands(),
 | 
					 | 
				
			||||||
                        device.load_statistics()])
 | 
					 | 
				
			||||||
                    self._devices.append(device)
 | 
					 | 
				
			||||||
            except json.JSONDecodeError:
 | 
					 | 
				
			||||||
                _LOGGER.error("No JSON Data after GET: %s", await resp.text())
 | 
					 | 
				
			||||||
                return False
 | 
					 | 
				
			||||||
        return True
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def load_commands(self, device: HonAppliance):
 | 
					    async def load_commands(self, appliance: HonAppliance):
 | 
				
			||||||
        params = {
 | 
					        params = {
 | 
				
			||||||
            "applianceType": device.appliance_type,
 | 
					            "applianceType": appliance.appliance_type,
 | 
				
			||||||
            "code": device.appliance["code"],
 | 
					            "code": appliance.info["code"],
 | 
				
			||||||
            "applianceModelId": device.appliance_model_id,
 | 
					            "applianceModelId": appliance.appliance_model_id,
 | 
				
			||||||
            "firmwareId": device.appliance["eepromId"],
 | 
					            "firmwareId": appliance.info["eepromId"],
 | 
				
			||||||
            "macAddress": device.mac_address,
 | 
					            "macAddress": appliance.mac_address,
 | 
				
			||||||
            "fwVersion": device.appliance["fwVersion"],
 | 
					            "fwVersion": appliance.info["fwVersion"],
 | 
				
			||||||
            "os": const.OS,
 | 
					            "os": const.OS,
 | 
				
			||||||
            "appVersion": const.APP_VERSION,
 | 
					            "appVersion": const.APP_VERSION,
 | 
				
			||||||
            "series": device.appliance["series"],
 | 
					            "series": appliance.info["series"],
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        url = f"{const.API_URL}/commands/v1/retrieve"
 | 
					        url = f"{const.API_URL}/commands/v1/retrieve"
 | 
				
			||||||
        async with self._hon.get(url, params=params) as response:
 | 
					        async with self._hon.get(url, params=params) as response:
 | 
				
			||||||
@@ -71,51 +50,51 @@ class HonAPI:
 | 
				
			|||||||
                return {}
 | 
					                return {}
 | 
				
			||||||
            return result
 | 
					            return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def command_history(self, device: HonAppliance):
 | 
					    async def command_history(self, appliance: HonAppliance):
 | 
				
			||||||
        url = f"{const.API_URL}/commands/v1/appliance/{device.mac_address}/history"
 | 
					        url = f"{const.API_URL}/commands/v1/appliance/{appliance.mac_address}/history"
 | 
				
			||||||
        async with self._hon.get(url) as response:
 | 
					        async with self._hon.get(url) as response:
 | 
				
			||||||
            result = await response.json()
 | 
					            result = await response.json()
 | 
				
			||||||
            if not result or not result.get("payload"):
 | 
					            if not result or not result.get("payload"):
 | 
				
			||||||
                return {}
 | 
					                return {}
 | 
				
			||||||
            return result["payload"]["history"]
 | 
					            return result["payload"]["history"]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def last_activity(self, device: HonAppliance):
 | 
					    async def last_activity(self, appliance: HonAppliance):
 | 
				
			||||||
        url = f"{const.API_URL}/commands/v1/retrieve-last-activity"
 | 
					        url = f"{const.API_URL}/commands/v1/retrieve-last-activity"
 | 
				
			||||||
        params = {"macAddress": device.mac_address}
 | 
					        params = {"macAddress": appliance.mac_address}
 | 
				
			||||||
        async with self._hon.get(url, params=params) as response:
 | 
					        async with self._hon.get(url, params=params) as response:
 | 
				
			||||||
            result = await response.json()
 | 
					            result = await response.json()
 | 
				
			||||||
            if result and (activity := result.get("attributes")):
 | 
					            if result and (activity := result.get("attributes")):
 | 
				
			||||||
                return activity
 | 
					                return activity
 | 
				
			||||||
        return {}
 | 
					        return {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def load_attributes(self, device: HonAppliance):
 | 
					    async def load_attributes(self, appliance: HonAppliance):
 | 
				
			||||||
        params = {
 | 
					        params = {
 | 
				
			||||||
            "macAddress": device.mac_address,
 | 
					            "macAddress": appliance.mac_address,
 | 
				
			||||||
            "applianceType": device.appliance_type,
 | 
					            "applianceType": appliance.appliance_type,
 | 
				
			||||||
            "category": "CYCLE"
 | 
					            "category": "CYCLE"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        url = f"{const.API_URL}/commands/v1/context"
 | 
					        url = f"{const.API_URL}/commands/v1/context"
 | 
				
			||||||
        async with self._hon.get(url, params=params) as response:
 | 
					        async with self._hon.get(url, params=params) as response:
 | 
				
			||||||
            return (await response.json()).get("payload", {})
 | 
					            return (await response.json()).get("payload", {})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def load_statistics(self, device: HonAppliance):
 | 
					    async def load_statistics(self, appliance: HonAppliance):
 | 
				
			||||||
        params = {
 | 
					        params = {
 | 
				
			||||||
            "macAddress": device.mac_address,
 | 
					            "macAddress": appliance.mac_address,
 | 
				
			||||||
            "applianceType": device.appliance_type
 | 
					            "applianceType": appliance.appliance_type
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        url = f"{const.API_URL}/commands/v1/statistics"
 | 
					        url = f"{const.API_URL}/commands/v1/statistics"
 | 
				
			||||||
        async with self._hon.get(url, params=params) as response:
 | 
					        async with self._hon.get(url, params=params) as response:
 | 
				
			||||||
            return (await response.json()).get("payload", {})
 | 
					            return (await response.json()).get("payload", {})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def send_command(self, device, command, parameters, ancillary_parameters):
 | 
					    async def send_command(self, appliance, command, parameters, ancillary_parameters):
 | 
				
			||||||
        now = datetime.utcnow().isoformat()
 | 
					        now = datetime.utcnow().isoformat()
 | 
				
			||||||
        data = {
 | 
					        data = {
 | 
				
			||||||
            "macAddress": device.mac_address,
 | 
					            "macAddress": appliance.mac_address,
 | 
				
			||||||
            "timestamp": f"{now[:-3]}Z",
 | 
					            "timestamp": f"{now[:-3]}Z",
 | 
				
			||||||
            "commandName": command,
 | 
					            "commandName": command,
 | 
				
			||||||
            "transactionId": f"{device.mac_address}_{now[:-3]}Z",
 | 
					            "transactionId": f"{appliance.mac_address}_{now[:-3]}Z",
 | 
				
			||||||
            "applianceOptions": device.commands_options,
 | 
					            "applianceOptions": appliance.commands_options,
 | 
				
			||||||
            "device": self._hon.device.get(),
 | 
					            "appliance": self._hon.device.get(),
 | 
				
			||||||
            "attributes": {
 | 
					            "attributes": {
 | 
				
			||||||
                "channel": "mobileApp",
 | 
					                "channel": "mobileApp",
 | 
				
			||||||
                "origin": "standardProgram",
 | 
					                "origin": "standardProgram",
 | 
				
			||||||
@@ -123,15 +102,12 @@ class HonAPI:
 | 
				
			|||||||
            },
 | 
					            },
 | 
				
			||||||
            "ancillaryParameters": ancillary_parameters,
 | 
					            "ancillaryParameters": ancillary_parameters,
 | 
				
			||||||
            "parameters": parameters,
 | 
					            "parameters": parameters,
 | 
				
			||||||
            "applianceType": device.appliance_type
 | 
					            "applianceType": appliance.appliance_type
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        url = f"{const.API_URL}/commands/v1/send"
 | 
					        url = f"{const.API_URL}/commands/v1/send"
 | 
				
			||||||
        async with self._hon.post(url, json=data) as resp:
 | 
					        async with self._hon.post(url, json=data) as resp:
 | 
				
			||||||
            try:
 | 
					            json_data = await resp.json()
 | 
				
			||||||
                json_data = await resp.json()
 | 
					            if json_data.get("payload", {}).get("resultCode") == "0":
 | 
				
			||||||
            except json.JSONDecodeError:
 | 
					 | 
				
			||||||
                return False
 | 
					 | 
				
			||||||
            if json_data["payload"]["resultCode"] == "0":
 | 
					 | 
				
			||||||
                return True
 | 
					                return True
 | 
				
			||||||
        return False
 | 
					        return False
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -164,3 +140,6 @@ class HonAPI:
 | 
				
			|||||||
                if result := await response.json():
 | 
					                if result := await response.json():
 | 
				
			||||||
                    return result
 | 
					                    return result
 | 
				
			||||||
        return {}
 | 
					        return {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def close(self):
 | 
				
			||||||
 | 
					        await self._hon.close()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,10 +1,8 @@
 | 
				
			|||||||
import datetime
 | 
					 | 
				
			||||||
import json
 | 
					import json
 | 
				
			||||||
import logging
 | 
					import logging
 | 
				
			||||||
import re
 | 
					import re
 | 
				
			||||||
import secrets
 | 
					import secrets
 | 
				
			||||||
import urllib
 | 
					import urllib
 | 
				
			||||||
from pprint import pprint
 | 
					 | 
				
			||||||
from urllib import parse
 | 
					from urllib import parse
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from yarl import URL
 | 
					from yarl import URL
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -1,3 +1,4 @@
 | 
				
			|||||||
 | 
					import json
 | 
				
			||||||
from contextlib import asynccontextmanager
 | 
					from contextlib import asynccontextmanager
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import aiohttp
 | 
					import aiohttp
 | 
				
			||||||
@@ -15,14 +16,14 @@ class HonBaseConnectionHandler:
 | 
				
			|||||||
        self._auth = None
 | 
					        self._auth = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def __aenter__(self):
 | 
					    async def __aenter__(self):
 | 
				
			||||||
        await self.create()
 | 
					        return await self.create()
 | 
				
			||||||
        return self
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def __aexit__(self, exc_type, exc_val, exc_tb):
 | 
					    async def __aexit__(self, exc_type, exc_val, exc_tb):
 | 
				
			||||||
        await self.close()
 | 
					        await self.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def create(self):
 | 
					    async def create(self):
 | 
				
			||||||
        self._session = aiohttp.ClientSession(headers=self._HEADERS)
 | 
					        self._session = aiohttp.ClientSession(headers=self._HEADERS)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @asynccontextmanager
 | 
					    @asynccontextmanager
 | 
				
			||||||
    async def get(self, *args, **kwargs):
 | 
					    async def get(self, *args, **kwargs):
 | 
				
			||||||
@@ -55,6 +56,7 @@ class HonConnectionHandler(HonBaseConnectionHandler):
 | 
				
			|||||||
    async def create(self):
 | 
					    async def create(self):
 | 
				
			||||||
        await super().create()
 | 
					        await super().create()
 | 
				
			||||||
        self._auth = HonAuth(self._session, self._email, self._password, self._device)
 | 
					        self._auth = HonAuth(self._session, self._email, self._password, self._device)
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async def _check_headers(self, headers):
 | 
					    async def _check_headers(self, headers):
 | 
				
			||||||
        if "cognito-token" not in self._request_headers or "id-token" not in self._request_headers:
 | 
					        if "cognito-token" not in self._request_headers or "id-token" not in self._request_headers:
 | 
				
			||||||
@@ -81,7 +83,13 @@ class HonConnectionHandler(HonBaseConnectionHandler):
 | 
				
			|||||||
                _LOGGER.error("%s - Error %s - %s", response.request_info.url, response.status, await response.text())
 | 
					                _LOGGER.error("%s - Error %s - %s", response.request_info.url, response.status, await response.text())
 | 
				
			||||||
                raise PermissionError("Login failure")
 | 
					                raise PermissionError("Login failure")
 | 
				
			||||||
            else:
 | 
					            else:
 | 
				
			||||||
                yield response
 | 
					                try:
 | 
				
			||||||
 | 
					                    await response.json()
 | 
				
			||||||
 | 
					                    yield response
 | 
				
			||||||
 | 
					                except json.JSONDecodeError:
 | 
				
			||||||
 | 
					                    _LOGGER.warning("%s - JsonDecodeError %s - %s", response.request_info.url, response.status,
 | 
				
			||||||
 | 
					                                    await response.text())
 | 
				
			||||||
 | 
					                    yield {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    @asynccontextmanager
 | 
					    @asynccontextmanager
 | 
				
			||||||
    async def get(self, *args, **kwargs):
 | 
					    async def get(self, *args, **kwargs):
 | 
				
			||||||
							
								
								
									
										36
									
								
								pyhon/hon.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								pyhon/hon.py
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,36 @@
 | 
				
			|||||||
 | 
					import asyncio
 | 
				
			||||||
 | 
					from typing import List
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from pyhon import HonAPI
 | 
				
			||||||
 | 
					from pyhon.appliance import HonAppliance
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Hon:
 | 
				
			||||||
 | 
					    def __init__(self, email, password):
 | 
				
			||||||
 | 
					        self._email = email
 | 
				
			||||||
 | 
					        self._password = password
 | 
				
			||||||
 | 
					        self._appliances = []
 | 
				
			||||||
 | 
					        self._api = None
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def __aenter__(self):
 | 
				
			||||||
 | 
					        self._api = await HonAPI(self._email, self._password).create()
 | 
				
			||||||
 | 
					        await self.setup()
 | 
				
			||||||
 | 
					        return self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def __aexit__(self, exc_type, exc_val, exc_tb):
 | 
				
			||||||
 | 
					        await self._api.close()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @property
 | 
				
			||||||
 | 
					    def appliances(self) -> List[HonAppliance]:
 | 
				
			||||||
 | 
					        return self._appliances
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    async def setup(self):
 | 
				
			||||||
 | 
					        for appliance in (await self._api.load_appliances())["payload"]["appliances"]:
 | 
				
			||||||
 | 
					            appliance = HonAppliance(self._api, appliance)
 | 
				
			||||||
 | 
					            if appliance.mac_address is None:
 | 
				
			||||||
 | 
					                continue
 | 
				
			||||||
 | 
					            await asyncio.gather(*[
 | 
				
			||||||
 | 
					                appliance.load_attributes(),
 | 
				
			||||||
 | 
					                appliance.load_commands(),
 | 
				
			||||||
 | 
					                appliance.load_statistics()])
 | 
				
			||||||
 | 
					            self._appliances.append(appliance)
 | 
				
			||||||
		Reference in New Issue
	
	Block a user