Skip to content

Commit 647adcc

Browse files
committed
feat: recover network connection after a 2-minute delay
1 parent 0954b00 commit 647adcc

1 file changed

Lines changed: 44 additions & 12 deletions

File tree

custom_components/xiaomi_home/miot/miot_client.py

Lines changed: 44 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,13 @@
7979
_LOGGER = logging.getLogger(__name__)
8080

8181

82+
RECOVER_NETWORK_DELAY = 120
83+
RECOVER_NETWORK_RETRY_DELAY = 600
84+
REFRESH_PROPS_DELAY = 0.2
85+
REFRESH_PROPS_RETRY_DELAY = 3
86+
REFRESH_CLOUD_DEVICES_DELAY = 6
87+
REFRESH_GATEWAY_DEVICES_DELAY = 3
88+
8289
@dataclass
8390
class MIoTClientSub:
8491
"""MIoT client subscription."""
@@ -156,6 +163,7 @@ class MIoTClient:
156163
_sub_device_state: dict[str, MipsDeviceState]
157164

158165
_mips_local_state_changed_timers: dict[str, asyncio.TimerHandle]
166+
_recover_network_timer: Optional[asyncio.TimerHandle]
159167
_refresh_token_timer: Optional[asyncio.TimerHandle]
160168
_refresh_cert_timer: Optional[asyncio.TimerHandle]
161169
_refresh_cloud_devices_timer: Optional[asyncio.TimerHandle]
@@ -226,6 +234,7 @@ def __init__(
226234
self._sub_device_state = {}
227235

228236
self._mips_local_state_changed_timers = {}
237+
self._recover_network_timer = None
229238
self._refresh_token_timer = None
230239
self._refresh_cert_timer = None
231240
self._refresh_cloud_devices_timer = None
@@ -406,6 +415,10 @@ async def deinit_async(self) -> None:
406415
devices=list(self._device_list_cache.keys()))
407416
await self._miot_lan.vote_for_lan_ctrl_async(
408417
key=f'{self._uid}-{self._cloud_server}', vote=False)
418+
# Cancel recover network
419+
if self._recover_network_timer:
420+
self._recover_network_timer.cancel()
421+
self._recover_network_timer = None
409422
# Cancel refresh auth info
410423
if self._refresh_token_timer:
411424
self._refresh_token_timer.cancel()
@@ -717,7 +730,7 @@ def request_refresh_prop(
717730
if self._refresh_props_timer:
718731
return
719732
self._refresh_props_timer = self._main_loop.call_later(
720-
0.2, lambda: self._main_loop.create_task(
733+
REFRESH_PROPS_DELAY, lambda: self._main_loop.create_task(
721734
self.__refresh_props_handler()))
722735

723736
async def get_prop_async(self, did: str, siid: int, piid: int) -> Any:
@@ -1022,14 +1035,13 @@ def __update_device_msg_sub(self, did: str) -> None:
10221035
@final
10231036
async def __on_network_status_changed(self, status: bool) -> None:
10241037
_LOGGER.info('network status changed, %s', status)
1038+
if self._recover_network_timer:
1039+
self._recover_network_timer.cancel()
1040+
self._recover_network_timer = None
10251041
if status:
1026-
# Check auth_info
1027-
if await self.refresh_oauth_info_async():
1028-
# Connect to mips cloud
1029-
self._mips_cloud.connect()
1030-
# Update device list
1031-
self.__request_refresh_cloud_devices()
1032-
await self.refresh_user_cert_async()
1042+
self._recover_network_timer = self._main_loop.call_later(
1043+
RECOVER_NETWORK_DELAY, lambda: self._main_loop.create_task(
1044+
self.__recover_network_async()))
10331045
else:
10341046
self.__request_show_devices_changed_notify(delay_sec=30)
10351047
# Cancel refresh cloud devices
@@ -1039,6 +1051,25 @@ async def __on_network_status_changed(self, status: bool) -> None:
10391051
# Disconnect cloud mips
10401052
self._mips_cloud.disconnect()
10411053

1054+
@final
1055+
async def __recover_network_async(self) -> None:
1056+
_LOGGER.info('recover network connection')
1057+
if self._recover_network_timer:
1058+
self._recover_network_timer.cancel()
1059+
self._recover_network_timer = None
1060+
# Check auth_info
1061+
if await self.refresh_oauth_info_async():
1062+
# Connect to mips cloud
1063+
self._mips_cloud.connect()
1064+
# Update device list
1065+
self.__request_refresh_cloud_devices()
1066+
else:
1067+
self._recover_network_timer = self._main_loop.call_later(
1068+
RECOVER_NETWORK_RETRY_DELAY,
1069+
lambda: self._main_loop.create_task(
1070+
self.__recover_network_async()))
1071+
await self.refresh_user_cert_async()
1072+
10421073
@final
10431074
async def __on_mips_service_state_change(
10441075
self, group_id: str, state: MipsServiceState, data: dict
@@ -1495,7 +1526,7 @@ def __request_refresh_cloud_devices(self, immediately=False) -> None:
14951526
if self._refresh_cloud_devices_timer:
14961527
return
14971528
self._refresh_cloud_devices_timer = self._main_loop.call_later(
1498-
6, lambda: self._main_loop.create_task(
1529+
REFRESH_CLOUD_DEVICES_DELAY, lambda: self._main_loop.create_task(
14991530
self.__refresh_cloud_devices_async()))
15001531

15011532
@final
@@ -1619,7 +1650,8 @@ def __request_refresh_gw_devices_by_group_id(
16191650
return
16201651
self._mips_local_state_changed_timers[group_id] = (
16211652
self._main_loop.call_later(
1622-
3, lambda: self._main_loop.create_task(
1653+
REFRESH_GATEWAY_DEVICES_DELAY,
1654+
lambda: self._main_loop.create_task(
16231655
self.__refresh_gw_devices_with_group_id_async(
16241656
group_id=group_id))))
16251657

@@ -1773,7 +1805,7 @@ async def __refresh_props_handler(self) -> None:
17731805
self._refresh_props_retry_count = 0
17741806
if self._refresh_props_list:
17751807
self._refresh_props_timer = self._main_loop.call_later(
1776-
0.2, lambda: self._main_loop.create_task(
1808+
REFRESH_PROPS_DELAY, lambda: self._main_loop.create_task(
17771809
self.__refresh_props_handler()))
17781810
else:
17791811
self._refresh_props_timer = None
@@ -1792,7 +1824,7 @@ async def __refresh_props_handler(self) -> None:
17921824
_LOGGER.info(
17931825
'refresh props failed, retry, %s', self._refresh_props_retry_count)
17941826
self._refresh_props_timer = self._main_loop.call_later(
1795-
3, lambda: self._main_loop.create_task(
1827+
REFRESH_PROPS_RETRY_DELAY, lambda: self._main_loop.create_task(
17961828
self.__refresh_props_handler()))
17971829

17981830
@final

0 commit comments

Comments
 (0)