Skip to content

Commit

Permalink
perf(remote): add asyncio.lock to pervent duplicated commands, and ig…
Browse files Browse the repository at this point in the history
…nore None dp codes
  • Loading branch information
xZetsubou committed Nov 16, 2024
1 parent 763ccdb commit 54593b5
Showing 1 changed file with 40 additions and 32 deletions.
72 changes: 40 additions & 32 deletions custom_components/localtuya/remote.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ def __init__(
self._dp_key_study = self._config.get(CONF_KEY_STUDY_DP)

self._device_id = self._device_config.id
self._lock = asyncio.Lock()

# self._attr_activity_list: list = []
# self._attr_current_activity: str | None = None
Expand Down Expand Up @@ -181,43 +182,50 @@ async def async_learn_command(self, **kwargs: Any) -> None:
if not self._storage_loaded:
await self._async_load_storage()

for command in commands:
last_code = self._last_code
await self.send_signal(ControlMode.STUDY)
persistent_notification.async_create(
self.hass,
f"Press the '{command}' button.",
title="Learn command",
notification_id="learn_command",
)
if self._lock.locked():
return self.debug("The device is already in learning mode.")

async with self._lock:
for command in commands:
last_code = self._last_code
await self.send_signal(ControlMode.STUDY)
persistent_notification.async_create(
self.hass,
f"Press the '{command}' button.",
title="Learn command",
notification_id="learn_command",
)

try:
self.debug(f"Waiting for code from DP: {self._dp_recieve}")
while now < timeout:
if last_code != (dp_code := self.dp_value(self._dp_recieve)):
self._last_code = dp_code
sucess = True
try:
self.debug(f"Waiting for code from DP: {self._dp_recieve}")
while now < timeout:
if (
last_code != (dp_code := self.dp_value(self._dp_recieve))
and dp_code is not None
):
self._last_code = dp_code
sucess = True
await self.send_signal(ControlMode.STUDY_EXIT)
break

now += 1
await asyncio.sleep(1)

if not sucess:
await self.send_signal(ControlMode.STUDY_EXIT)
break

now += 1
await asyncio.sleep(1)

if not sucess:
await self.send_signal(ControlMode.STUDY_EXIT)
raise ServiceValidationError(f"Failed to learn: {command}")
raise ServiceValidationError(f"Failed to learn: {command}")

finally:
persistent_notification.async_dismiss(
self.hass, notification_id="learn_command"
)
finally:
persistent_notification.async_dismiss(
self.hass, notification_id="learn_command"
)

# code retrive sucess and it's sotred in self._last_code
# we will store the codes.
await self._save_new_command(device, command, self._last_code)
# code retrive sucess and it's sotred in self._last_code
# we will store the codes.
await self._save_new_command(device, command, self._last_code)

if command != commands[-1]:
await asyncio.sleep(1)
if command != commands[-1]:
await asyncio.sleep(1)

async def async_delete_command(self, **kwargs: Any) -> None:
"""Delete commands from the database."""
Expand Down

0 comments on commit 54593b5

Please sign in to comment.