Compare commits
3 Commits
Author | SHA1 | Date | |
---|---|---|---|
44f40c531e | |||
4e88bc7a9f | |||
b5d8a90d79 |
@ -165,7 +165,9 @@ class HonAppliance:
|
|||||||
|
|
||||||
async def load_attributes(self) -> None:
|
async def load_attributes(self) -> None:
|
||||||
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()
|
||||||
|
):
|
||||||
if name in self._attributes.get("parameters", {}):
|
if name in self._attributes.get("parameters", {}):
|
||||||
self._attributes["parameters"][name].update(values)
|
self._attributes["parameters"][name].update(values)
|
||||||
else:
|
else:
|
||||||
|
@ -15,7 +15,7 @@ class Appliance(ApplianceBase):
|
|||||||
|
|
||||||
data["active"] = data["parameters"]["onOffStatus"] == "1"
|
data["active"] = data["parameters"]["onOffStatus"] == "1"
|
||||||
|
|
||||||
if program := int(data["parameters"]["prCode"]):
|
if program := int(data["parameters"]["prCode"].value):
|
||||||
if (setting := self.parent.settings["startProgram.program"]) and isinstance(
|
if (setting := self.parent.settings["startProgram.program"]) and isinstance(
|
||||||
setting, HonParameterProgram
|
setting, HonParameterProgram
|
||||||
):
|
):
|
||||||
|
@ -55,7 +55,7 @@ class HonCommandLoader:
|
|||||||
async def load_commands(self) -> None:
|
async def load_commands(self) -> None:
|
||||||
"""Trigger loading of command data"""
|
"""Trigger loading of command data"""
|
||||||
await self._load_data()
|
await self._load_data()
|
||||||
self._appliance_data = self._api_commands.pop("applianceModel")
|
self._appliance_data = self._api_commands.pop("applianceModel", {})
|
||||||
self._get_commands()
|
self._get_commands()
|
||||||
self._add_favourites()
|
self._add_favourites()
|
||||||
self._recover_last_command_states()
|
self._recover_last_command_states()
|
||||||
|
@ -250,9 +250,11 @@ class TestAPI(HonAPI):
|
|||||||
|
|
||||||
def _load_json(self, appliance: HonAppliance, file: str) -> Dict[str, Any]:
|
def _load_json(self, appliance: HonAppliance, file: str) -> Dict[str, Any]:
|
||||||
directory = f"{appliance.appliance_type}_{appliance.appliance_model_id}".lower()
|
directory = f"{appliance.appliance_type}_{appliance.appliance_model_id}".lower()
|
||||||
path = f"{self._path}/{directory}/{file}.json"
|
if (path := self._path / directory / f"{file}.json").exists():
|
||||||
with open(path, "r", encoding="utf-8") as json_file:
|
with open(path, "r", encoding="utf-8") as json_file:
|
||||||
return json.loads(json_file.read())
|
return json.loads(json_file.read())
|
||||||
|
_LOGGER.warning(f"Can't open {str(path)}")
|
||||||
|
return {}
|
||||||
|
|
||||||
async def load_appliances(self) -> List[Dict[str, Any]]:
|
async def load_appliances(self) -> List[Dict[str, Any]]:
|
||||||
result = []
|
result = []
|
||||||
|
@ -4,6 +4,7 @@ from contextlib import asynccontextmanager
|
|||||||
from typing import Dict, Any
|
from typing import Dict, Any
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
from yarl import URL
|
||||||
|
|
||||||
from pyhon import const
|
from pyhon import const
|
||||||
from pyhon.connection.handler.base import ConnectionHandler
|
from pyhon.connection.handler.base import ConnectionHandler
|
||||||
@ -17,10 +18,10 @@ class HonAnonymousConnectionHandler(ConnectionHandler):
|
|||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def _intercept(
|
async def _intercept(
|
||||||
self, method: Callback, *args: Any, **kwargs: Any
|
self, method: Callback, url: str | URL, *args: Any, **kwargs: Dict[str, Any]
|
||||||
) -> AsyncIterator[aiohttp.ClientResponse]:
|
) -> AsyncIterator[aiohttp.ClientResponse]:
|
||||||
kwargs["headers"] = kwargs.pop("headers", {}) | self._HEADERS
|
kwargs["headers"] = kwargs.pop("headers", {}) | self._HEADERS
|
||||||
async with method(*args, **kwargs) as response:
|
async with method(url, *args, **kwargs) as response:
|
||||||
if response.status == 403:
|
if response.status == 403:
|
||||||
_LOGGER.error("Can't authenticate anymore")
|
_LOGGER.error("Can't authenticate anymore")
|
||||||
yield response
|
yield response
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
import logging
|
import logging
|
||||||
from collections.abc import AsyncIterator
|
from collections.abc import AsyncIterator
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from typing import Optional, List, Tuple, Any
|
from typing import Optional, List, Tuple, Any, Dict
|
||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
|
from yarl import URL
|
||||||
|
|
||||||
from pyhon import const
|
from pyhon import const
|
||||||
from pyhon.connection.handler.base import ConnectionHandler
|
from pyhon.connection.handler.base import ConnectionHandler
|
||||||
@ -29,9 +30,9 @@ class HonAuthConnectionHandler(ConnectionHandler):
|
|||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def _intercept(
|
async def _intercept(
|
||||||
self, method: Callback, *args: Any, **kwargs: Any
|
self, method: Callback, url: str | URL, *args: Any, **kwargs: Dict[str, Any]
|
||||||
) -> AsyncIterator[aiohttp.ClientResponse]:
|
) -> AsyncIterator[aiohttp.ClientResponse]:
|
||||||
kwargs["headers"] = kwargs.pop("headers", {}) | self._HEADERS
|
kwargs["headers"] = kwargs.pop("headers", {}) | self._HEADERS
|
||||||
async with method(*args, **kwargs) as response:
|
async with method(url, *args, **kwargs) as response:
|
||||||
self._called_urls.append((response.status, str(response.request_info.url)))
|
self._called_urls.append((response.status, str(response.request_info.url)))
|
||||||
yield response
|
yield response
|
||||||
|
@ -6,6 +6,7 @@ from typing import Optional, Dict, Type, Any, Protocol
|
|||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from typing_extensions import Self
|
from typing_extensions import Self
|
||||||
|
from yarl import URL
|
||||||
|
|
||||||
from pyhon import const, exceptions
|
from pyhon import const, exceptions
|
||||||
from pyhon.typedefs import Callback
|
from pyhon.typedefs import Callback
|
||||||
@ -47,7 +48,7 @@ class ConnectionHandler:
|
|||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
def _intercept(
|
def _intercept(
|
||||||
self, method: Callback, *args: Any, loop: int = 0, **kwargs: Any
|
self, method: Callback, url: str | URL, *args: Any, **kwargs: Dict[str, Any]
|
||||||
) -> AsyncIterator[aiohttp.ClientResponse]:
|
) -> AsyncIterator[aiohttp.ClientResponse]:
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ from typing import Optional, Dict, Any
|
|||||||
|
|
||||||
import aiohttp
|
import aiohttp
|
||||||
from typing_extensions import Self
|
from typing_extensions import Self
|
||||||
|
from yarl import URL
|
||||||
|
|
||||||
from pyhon.connection.auth import HonAuth
|
from pyhon.connection.auth import HonAuth
|
||||||
from pyhon.connection.device import HonDevice
|
from pyhon.connection.device import HonDevice
|
||||||
@ -54,16 +55,19 @@ class HonConnectionHandler(ConnectionHandler):
|
|||||||
|
|
||||||
@asynccontextmanager
|
@asynccontextmanager
|
||||||
async def _intercept(
|
async def _intercept(
|
||||||
self, method: Callback, *args: Any, loop: int = 0, **kwargs: Dict[str, str]
|
self, method: Callback, url: str | URL, *args: Any, **kwargs: Any
|
||||||
) -> AsyncIterator[aiohttp.ClientResponse]:
|
) -> AsyncIterator[aiohttp.ClientResponse]:
|
||||||
|
loop: int = kwargs.pop("loop", 0)
|
||||||
kwargs["headers"] = await self._check_headers(kwargs.get("headers", {}))
|
kwargs["headers"] = await self._check_headers(kwargs.get("headers", {}))
|
||||||
async with method(args[0], *args[1:], **kwargs) as response:
|
async with method(url, *args, **kwargs) as response:
|
||||||
if (
|
if (
|
||||||
self.auth.token_expires_soon or response.status in [401, 403]
|
self.auth.token_expires_soon or response.status in [401, 403]
|
||||||
) and loop == 0:
|
) and loop == 0:
|
||||||
_LOGGER.info("Try refreshing token...")
|
_LOGGER.info("Try refreshing token...")
|
||||||
await self.auth.refresh()
|
await self.auth.refresh()
|
||||||
async with self._intercept(method, loop=loop + 1, **kwargs) as result:
|
async with self._intercept(
|
||||||
|
method, url, *args, loop=loop + 1, **kwargs
|
||||||
|
) as result:
|
||||||
yield result
|
yield result
|
||||||
elif (
|
elif (
|
||||||
self.auth.token_is_expired or response.status in [401, 403]
|
self.auth.token_is_expired or response.status in [401, 403]
|
||||||
@ -75,7 +79,9 @@ class HonConnectionHandler(ConnectionHandler):
|
|||||||
await response.text(),
|
await response.text(),
|
||||||
)
|
)
|
||||||
await self.create()
|
await self.create()
|
||||||
async with self._intercept(method, loop=loop + 1, **kwargs) as result:
|
async with self._intercept(
|
||||||
|
method, url, *args, loop=loop + 1, **kwargs
|
||||||
|
) as result:
|
||||||
yield result
|
yield result
|
||||||
elif loop >= 2:
|
elif loop >= 2:
|
||||||
_LOGGER.error(
|
_LOGGER.error(
|
||||||
|
@ -70,7 +70,7 @@ async def zip_archive(
|
|||||||
) -> str:
|
) -> str:
|
||||||
data = await appliance_data(appliance, path, anonymous)
|
data = await appliance_data(appliance, path, anonymous)
|
||||||
archive = data[0].parent
|
archive = data[0].parent
|
||||||
shutil.make_archive(str(archive.parent), "zip", archive)
|
shutil.make_archive(str(archive), "zip", archive)
|
||||||
shutil.rmtree(archive)
|
shutil.rmtree(archive)
|
||||||
return f"{archive.stem}.zip"
|
return f"{archive.stem}.zip"
|
||||||
|
|
||||||
|
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.14.3",
|
version="0.14.6",
|
||||||
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