Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: support entities filter & optimize the network detection logic #458

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 26 additions & 24 deletions custom_components/xiaomi_home/miot/miot_cloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -224,20 +224,20 @@ class MIoTHttpClient:
_client_id: str
_access_token: str

_get_prop_timer: asyncio.TimerHandle
_get_prop_list: dict[str, dict[str, asyncio.Future | str | bool]]
_get_prop_timer: Optional[asyncio.TimerHandle]
_get_prop_list: dict[str, dict]

def __init__(
self, cloud_server: str, client_id: str, access_token: str,
loop: Optional[asyncio.AbstractEventLoop] = None
) -> None:
self._main_loop = loop or asyncio.get_running_loop()
self._host = None
self._base_url = None
self._client_id = None
self._access_token = None
self._host = DEFAULT_OAUTH2_API_HOST
self._base_url = ''
self._client_id = ''
self._access_token = ''

self._get_prop_timer: asyncio.TimerHandle = None
self._get_prop_timer = None
self._get_prop_list = {}

if (
Expand All @@ -258,8 +258,9 @@ async def deinit_async(self) -> None:
self._get_prop_timer.cancel()
self._get_prop_timer = None
for item in self._get_prop_list.values():
fut: asyncio.Future = item.get('fut')
fut.cancel()
fut: Optional[asyncio.Future] = item.get('fut', None)
if fut:
fut.cancel()
self._get_prop_list.clear()
if self._session and not self._session.closed:
await self._session.close()
Expand All @@ -270,9 +271,7 @@ def update_http_header(
access_token: Optional[str] = None
) -> None:
if isinstance(cloud_server, str):
if cloud_server == 'cn':
self._host = DEFAULT_OAUTH2_API_HOST
else:
if cloud_server != 'cn':
self._host = f'{cloud_server}.{DEFAULT_OAUTH2_API_HOST}'
self._base_url = f'https://{self._host}'
if isinstance(client_id, str):
Expand Down Expand Up @@ -350,8 +349,8 @@ async def __mihome_api_post_async(
async def get_user_info_async(self) -> dict:
http_res = await self._session.get(
url='https://open.account.xiaomi.com/user/profile',
params={'clientId': self._client_id,
'token': self._access_token},
params={
'clientId': self._client_id, 'token': self._access_token},
headers={'content-type': 'application/x-www-form-urlencoded'},
timeout=MIHOME_HTTP_API_TIMEOUT
)
Expand Down Expand Up @@ -386,7 +385,9 @@ async def get_central_cert_async(self, csr: str) -> Optional[str]:

return cert

async def __get_dev_room_page_async(self, max_id: str = None) -> dict:
async def __get_dev_room_page_async(
self, max_id: Optional[str] = None
) -> dict:
res_obj = await self.__mihome_api_post_async(
url_path='/app/v2/homeroom/get_dev_room_page',
data={
Expand Down Expand Up @@ -442,7 +443,7 @@ async def get_homeinfos_async(self) -> dict:
if 'result' not in res_obj:
raise MIoTHttpError('invalid response result')

uid: str = None
uid: Optional[str] = None
home_infos: dict = {}
for device_source in ['homelist', 'share_home_list']:
home_infos.setdefault(device_source, {})
Expand Down Expand Up @@ -507,7 +508,7 @@ async def get_uid_async(self) -> str:
return (await self.get_homeinfos_async()).get('uid', None)

async def __get_device_list_page_async(
self, dids: list[str], start_did: str = None
self, dids: list[str], start_did: Optional[str] = None
) -> dict[str, dict]:
req_data: dict = {
'limit': 200,
Expand Down Expand Up @@ -575,9 +576,9 @@ async def __get_device_list_page_async(

async def get_devices_with_dids_async(
self, dids: list[str]
) -> dict[str, dict]:
) -> Optional[dict[str, dict]]:
results: list[dict[str, dict]] = await asyncio.gather(
*[self.__get_device_list_page_async(dids[index:index+150])
*[self.__get_device_list_page_async(dids=dids[index:index+150])
for index in range(0, len(dids), 150)])
devices = {}
for result in results:
Expand All @@ -587,7 +588,7 @@ async def get_devices_with_dids_async(
return devices

async def get_devices_async(
self, home_ids: list[str] = None
self, home_ids: Optional[list[str]] = None
) -> dict[str, dict]:
homeinfos = await self.get_homeinfos_async()
homes: dict[str, dict[str, Any]] = {}
Expand Down Expand Up @@ -627,8 +628,9 @@ async def get_devices_async(
'group_id': group_id
} for did in room_info.get('dids', [])})
dids = sorted(list(devices.keys()))
results: dict[str, dict] = await self.get_devices_with_dids_async(
dids=dids)
results = await self.get_devices_with_dids_async(dids=dids)
if results is None:
raise MIoTHttpError('get devices failed')
for did in dids:
if did not in results:
devices.pop(did, None)
Expand Down Expand Up @@ -706,7 +708,7 @@ async def __get_prop_handler(self) -> bool:
key = f'{result["did"]}.{result["siid"]}.{result["piid"]}'
prop_obj = self._get_prop_list.pop(key, None)
if prop_obj is None:
_LOGGER.error('get prop error, key not exists, %s', result)
_LOGGER.info('get prop error, key not exists, %s', result)
continue
prop_obj['fut'].set_result(result['value'])
props_req.remove(key)
Expand All @@ -717,7 +719,7 @@ async def __get_prop_handler(self) -> bool:
continue
prop_obj['fut'].set_result(None)
if props_req:
_LOGGER.error(
_LOGGER.info(
'get prop from cloud failed, %s, %s', len(key), props_req)

if self._get_prop_list:
Expand Down
Loading