From 8bdb2d3e08e60839c0db93ea8f53ea6a39ef632c Mon Sep 17 00:00:00 2001 From: ollo69 <60491700+ollo69@users.noreply.github.com> Date: Sun, 19 Feb 2023 22:31:29 +0100 Subject: [PATCH] Review wash devices commands (issue #489) (#502) * Allow wake-up for Thinq2 device that support stand-by * Retry command execution to fix timeout --- .../smartthinq_sensors/switch.py | 2 +- .../wideq/devices/washerDryer.py | 66 ++++++++++++++----- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/custom_components/smartthinq_sensors/switch.py b/custom_components/smartthinq_sensors/switch.py index a169a547..727d3109 100644 --- a/custom_components/smartthinq_sensors/switch.py +++ b/custom_components/smartthinq_sensors/switch.py @@ -56,7 +56,7 @@ class ThinQSwitchEntityDescription(SwitchEntityDescription): value_fn=lambda x: x.is_power_on and not x.device.stand_by, turn_off_fn=lambda x: x.device.power_off(), turn_on_fn=lambda x: x.device.wake_up(), - available_fn=lambda x: x.is_power_on, + available_fn=lambda x: x.is_power_on or x.device.stand_by, ), ) REFRIGERATOR_SWITCH: Tuple[ThinQSwitchEntityDescription, ...] = ( diff --git a/custom_components/smartthinq_sensors/wideq/devices/washerDryer.py b/custom_components/smartthinq_sensors/wideq/devices/washerDryer.py index 7bb1cda5..1e0cffee 100644 --- a/custom_components/smartthinq_sensors/wideq/devices/washerDryer.py +++ b/custom_components/smartthinq_sensors/wideq/devices/washerDryer.py @@ -1,6 +1,7 @@ """------------------for Washer and Dryer""" from __future__ import annotations +import asyncio import base64 import json import logging @@ -237,7 +238,7 @@ def remote_start_enabled(self) -> bool: async def power_off(self): """Power off the device.""" keys = self._get_cmd_keys(CMD_POWER_OFF) - await self.set(keys[0], keys[1], value=keys[2]) + await self.set_with_retry(keys[0], keys[1], value=keys[2], num_retry=2) self._remote_start_status = None self._update_status(POWER_STATUS_KEY, STATE_WM_POWER_OFF) @@ -247,17 +248,7 @@ async def wake_up(self): raise InvalidDeviceStatus() keys = self._get_cmd_keys(CMD_WAKE_UP) - # we retry more times to wakeup - retry = 2 - for i in range(retry): - try: - await self.set(keys[0], keys[1], value=keys[2]) - except Exception as exc: # pylint: disable=broad-except - _LOGGER.warning( - "Error in wake-up %s, tentative %s: %s", self.name, i, exc - ) - if i == retry - 1: - raise + await self.set_with_retry(keys[0], keys[1], value=keys[2], num_retry=2) self._stand_by = False async def remote_start(self): @@ -266,7 +257,7 @@ async def remote_start(self): raise InvalidDeviceStatus() keys = self._get_cmd_keys(CMD_REMOTE_START) - await self.set(keys[0], keys[1], key=keys[2]) + await self.set_with_retry(keys[0], keys[1], key=keys[2], num_retry=2) async def set( self, ctrl_key, command, *, key=None, value=None, data=None, ctrl_path=None @@ -281,6 +272,43 @@ async def set( ctrl_path=ctrl_path, ) + async def set_with_retry( + self, + ctrl_key, + command, + *, + key=None, + value=None, + data=None, + ctrl_path=None, + num_retry=1, + ): + """Set a device's control for `key` to `value` with retry.""" + if num_retry <= 0: + num_retry = 1 + for i in range(num_retry): + try: + await self.set( + ctrl_key, + command, + key=key, + value=value, + data=data, + ctrl_path=ctrl_path, + ) + return + except Exception as exc: # pylint: disable=broad-except + if i == num_retry - 1: + raise + _LOGGER.debug( + "Device %s, error executing command %s, tentative %s: %s", + self.name, + command, + i, + exc, + ) + await asyncio.sleep(1) + def reset_status(self): tcl_count = None if self._status: @@ -290,10 +318,14 @@ def reset_status(self): def _set_remote_start_opt(self, res): """Save the status to use for remote start.""" - self._stand_by = ( - self._status.device_features.get(WashDeviceFeatures.STANDBY) - == StateOptions.ON - ) + standby_enable = self.model_info.config_value("standbyEnable") + if standby_enable and not self._should_poll: + self._stand_by = not self._status.is_on + else: + self._stand_by = ( + self._status.device_features.get(WashDeviceFeatures.STANDBY) + == StateOptions.ON + ) remote_start = self._status.device_features.get(WashDeviceFeatures.REMOTESTART) if remote_start == StateOptions.ON: if self._remote_start_status is None: