Просмотр исходного кода

Revert PR #4986 locking

This is causing too many unintended side effects due to serialising of
requests that used to be merged.

Issue #5145
Jason Rumney 11 часов назад
Родитель
Сommit
b291aea88e

+ 7 - 9
custom_components/tuya_local/alarm_control_panel.py

@@ -79,12 +79,11 @@ class TuyaLocalAlarmControlPanel(TuyaLocalEntity, AlarmControlPanelEntity):
             )
 
     async def _alarm_send_command(self, cmd: str):
-        async with self._device.set_lock:
-            _LOGGER.info("%s setting alarm state to %s", self._config.config_id, cmd)
-            if cmd in self._alarm_state_dp.values(self._device):
-                await self._alarm_state_dp.async_set_value(self._device, cmd)
-            else:
-                raise NotImplementedError()
+        _LOGGER.info("%s setting alarm state to %s", self._config.config_id, cmd)
+        if cmd in self._alarm_state_dp.values(self._device):
+            await self._alarm_state_dp.async_set_value(self._device, cmd)
+        else:
+            raise NotImplementedError()
 
     async def async_alarm_disarm(self, code=None):
         """Send disarm command"""
@@ -110,8 +109,7 @@ class TuyaLocalAlarmControlPanel(TuyaLocalEntity, AlarmControlPanelEntity):
 
     async def async_alarm_trigger(self, code=None):
         if self._trigger_dp:
-            async with self._device.set_lock:
-                _LOGGER.info("%s triggering alarm", self._config.config_id)
-                await self._trigger_dp.async_set_value(self._device, True)
+            _LOGGER.info("%s triggering alarm", self._config.config_id)
+            await self._trigger_dp.async_set_value(self._device, True)
         else:
             await self._alarm_send_command(AlarmControlPanelState.TRIGGERED)

+ 2 - 3
custom_components/tuya_local/button.py

@@ -57,6 +57,5 @@ class TuyaLocalButton(TuyaLocalEntity, ButtonEntity):
 
     async def async_press(self):
         """Press the button"""
-        async with self._device.set_lock:
-            _LOGGER.info("%s pressing button", self._config._device.config)
-            await self._button_dp.async_set_value(self._device, True)
+        _LOGGER.info("%s pressing button", self._config._device.config)
+        await self._button_dp.async_set_value(self._device, True)

+ 10 - 15
custom_components/tuya_local/camera.py

@@ -61,9 +61,8 @@ class TuyaLocalCamera(TuyaLocalEntity, CameraEntity):
 
     async def async_camera_image(self, width=None, height=None):
         if self._snapshot_dp:
-            async with self._device.set_lock:
-                _LOGGER.info("%s fetching snapshot", self._config.config_id)
-                return self._snapshot_dp.decoded_value(self._device)
+            _LOGGER.info("%s fetching snapshot", self._config.config_id)
+            return self._snapshot_dp.decoded_value(self._device)
 
     @property
     def is_on(self):
@@ -75,30 +74,26 @@ class TuyaLocalCamera(TuyaLocalEntity, CameraEntity):
         """Turn off the camera"""
         if not self._switch_dp:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info("%s turning off camera", self._config.config_id)
-            await self._switch_dp.async_set_value(self._device, False)
+        _LOGGER.info("%s turning off camera", self._config.config_id)
+        await self._switch_dp.async_set_value(self._device, False)
 
     async def async_turn_on(self):
         """Turn on the camera"""
         if not self._switch_dp:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info("%s turning on camera", self._config.config_id)
-            await self._switch_dp.async_set_value(self._device, True)
+        _LOGGER.info("%s turning on camera", self._config.config_id)
+        await self._switch_dp.async_set_value(self._device, True)
 
     async def async_enable_motion_detection(self):
         """Enable motion detection on the camera"""
         if not self._motion_enable_dp:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info("%s enabling motion detection", self._config.config_id)
-            await self._motion_enable_dp.async_set_value(self._device, True)
+        _LOGGER.info("%s enabling motion detection", self._config.config_id)
+        await self._motion_enable_dp.async_set_value(self._device, True)
 
     async def async_disable_motion_detection(self):
         """Disable motion detection on the camera"""
         if not self._motion_enable_dp:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info("%s disabling motion detection", self._config.config_id)
-            await self._motion_enable_dp.async_set_value(self._device, False)
+        _LOGGER.info("%s disabling motion detection", self._config.config_id)
+        await self._motion_enable_dp.async_set_value(self._device, False)

+ 62 - 71
custom_components/tuya_local/climate.py

@@ -275,26 +275,24 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         if self._temperature_dps is None:
             raise NotImplementedError()
 
-        async with self._device.set_lock:
-            await self._temperature_dps.async_set_value(
-                self._device,
-                target_temperature,
-            )
+        await self._temperature_dps.async_set_value(
+            self._device,
+            target_temperature,
+        )
 
     async def async_set_target_temperature_range(self, low, high):
         """Set the target temperature range."""
-        async with self._device.set_lock:
-            dps_map = {}
-            if low is not None and self._temp_low_dps is not None:
-                dps_map.update(
-                    self._temp_low_dps.get_values_to_set(self._device, low, dps_map),
-                )
-            if high is not None and self._temp_high_dps is not None:
-                dps_map.update(
-                    self._temp_high_dps.get_values_to_set(self._device, high, dps_map),
-                )
-            if dps_map:
-                await self._device.async_set_properties(dps_map)
+        dps_map = {}
+        if low is not None and self._temp_low_dps is not None:
+            dps_map.update(
+                self._temp_low_dps.get_values_to_set(self._device, low, dps_map),
+            )
+        if high is not None and self._temp_high_dps is not None:
+            dps_map.update(
+                self._temp_high_dps.get_values_to_set(self._device, high, dps_map),
+            )
+        if dps_map:
+            await self._device.async_set_properties(dps_map)
 
     @property
     def current_temperature(self):
@@ -335,13 +333,12 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         if self._humidity_dps is None:
             raise NotImplementedError()
 
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting humidity to %s",
-                self._config.config_id,
-                humidity,
-            )
-            await self._humidity_dps.async_set_value(self._device, humidity)
+        _LOGGER.info(
+            "%s setting humidity to %s",
+            self._config.config_id,
+            humidity,
+        )
+        await self._humidity_dps.async_set_value(self._device, humidity)
 
     @property
     def current_humidity(self):
@@ -396,22 +393,20 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         """Set new HVAC mode."""
         if self._hvac_mode_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting HVAC mode to %s",
-                self._config.config_id,
-                hvac_mode,
-            )
-            await self._hvac_mode_dps.async_set_value(self._device, hvac_mode)
+        _LOGGER.info(
+            "%s setting HVAC mode to %s",
+            self._config.config_id,
+            hvac_mode,
+        )
+        await self._hvac_mode_dps.async_set_value(self._device, hvac_mode)
 
     async def async_turn_on(self):
         """Turn on the climate device."""
         # Bypass the usual dps mapping to switch the power dp directly
         # this way the hvac_mode will be kept when toggling off and on.
         if self._hvac_mode_dps and self._hvac_mode_dps.type is bool:
-            async with self._device.set_lock:
-                _LOGGER.info("%s turning on", self._config.config_id)
-                await self._device.async_set_property(self._hvac_mode_dps.id, True)
+            _LOGGER.info("%s turning on", self._config.config_id)
+            await self._device.async_set_property(self._hvac_mode_dps.id, True)
         else:
             await super().async_turn_on()
 
@@ -420,12 +415,11 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         # Bypass the usual dps mapping to switch the power dp directly
         # this way the hvac_mode will be kept when toggling off and on.
         if self._hvac_mode_dps and self._hvac_mode_dps.type is bool:
-            async with self._device.set_lock:
-                _LOGGER.info("%s turning off", self._config.config_id)
-                await self._device.async_set_property(
-                    self._hvac_mode_dps.id,
-                    False,
-                )
+            _LOGGER.info("%s turning off", self._config.config_id)
+            await self._device.async_set_property(
+                self._hvac_mode_dps.id,
+                False,
+            )
         else:
             await super().async_turn_off()
 
@@ -434,6 +428,7 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         """Return the current preset mode."""
         if self._preset_mode_dps is None:
             raise NotImplementedError()
+
         return self._preset_mode_dps.get_value(self._device)
 
     @property
@@ -446,13 +441,12 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         """Set the preset mode."""
         if self._preset_mode_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting preset mode to %s",
-                self._config.config_id,
-                preset_mode,
-            )
-            await self._preset_mode_dps.async_set_value(self._device, preset_mode)
+        _LOGGER.info(
+            "%s setting preset mode to %s",
+            self._config.config_id,
+            preset_mode,
+        )
+        await self._preset_mode_dps.async_set_value(self._device, preset_mode)
 
     @property
     def swing_mode(self):
@@ -471,13 +465,12 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         """Set the preset mode."""
         if self._swing_mode_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting swing mode to %s",
-                self._config.config_id,
-                swing_mode,
-            )
-            await self._swing_mode_dps.async_set_value(self._device, swing_mode)
+        _LOGGER.info(
+            "%s setting swing mode to %s",
+            self._config.config_id,
+            swing_mode,
+        )
+        await self._swing_mode_dps.async_set_value(self._device, swing_mode)
 
     @property
     def swing_horizontal_mode(self):
@@ -496,16 +489,15 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         """Set the preset mode."""
         if self._swing_horizontal_mode_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting horizontal swing mode to %s",
-                self._config.config_id,
-                swing_mode,
-            )
-            await self._swing_horizontal_mode_dps.async_set_value(
-                self._device,
-                swing_mode,
-            )
+        _LOGGER.info(
+            "%s setting horizontal swing mode to %s",
+            self._config.config_id,
+            swing_mode,
+        )
+        await self._swing_horizontal_mode_dps.async_set_value(
+            self._device,
+            swing_mode,
+        )
 
     @property
     def fan_mode(self):
@@ -524,10 +516,9 @@ class TuyaLocalClimate(TuyaLocalEntity, ClimateEntity):
         """Set the fan mode."""
         if self._fan_mode_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting fan mode to %s",
-                self._config.config_id,
-                fan_mode,
-            )
-            await self._fan_mode_dps.async_set_value(self._device, fan_mode)
+        _LOGGER.info(
+            "%s setting fan mode to %s",
+            self._config.config_id,
+            fan_mode,
+        )
+        await self._fan_mode_dps.async_set_value(self._device, fan_mode)

+ 39 - 44
custom_components/tuya_local/cover.py

@@ -201,71 +201,66 @@ class TuyaLocalCover(TuyaLocalEntity, CoverEntity):
 
     async def async_open_cover(self, **kwargs):
         """Open the cover."""
-        async with self._device.set_lock:
-            if self._control_dp and "open" in self._control_dp.values(self._device):
-                _LOGGER.info("%s opening", self._config.config_id)
-                await self._control_dp.async_set_value(self._device, "open")
-            elif self._position_dp:
-                pos = 100
-                _LOGGER.info("%s opening to 100%%", self._config.config_id)
-                await self._position_dp.async_set_value(self._device, pos)
-            else:
-                raise NotImplementedError()
+        if self._control_dp and "open" in self._control_dp.values(self._device):
+            _LOGGER.info("%s opening", self._config.config_id)
+            await self._control_dp.async_set_value(self._device, "open")
+        elif self._position_dp:
+            pos = 100
+            _LOGGER.info("%s opening to 100%%", self._config.config_id)
+            await self._position_dp.async_set_value(self._device, pos)
+        else:
+            raise NotImplementedError()
 
     async def async_close_cover(self, **kwargs):
         """Close the cover."""
-        async with self._device.set_lock:
-            if self._control_dp and "close" in self._control_dp.values(self._device):
-                _LOGGER.info("%s closing", self._config.config_id)
-                await self._control_dp.async_set_value(self._device, "close")
-            elif self._position_dp:
-                pos = 0
-                _LOGGER.info("%s closing to 0%%", self._config.config_id)
-                await self._position_dp.async_set_value(self._device, pos)
-            else:
-                raise NotImplementedError()
+        if self._control_dp and "close" in self._control_dp.values(self._device):
+            _LOGGER.info("%s closing", self._config.config_id)
+            await self._control_dp.async_set_value(self._device, "close")
+        elif self._position_dp:
+            pos = 0
+            _LOGGER.info("%s closing to 0%%", self._config.config_id)
+            await self._position_dp.async_set_value(self._device, pos)
+        else:
+            raise NotImplementedError()
 
     async def async_set_cover_position(self, position, **kwargs):
         """Set the cover to a specific position."""
         if position is None:
             raise AttributeError()
         if self._position_dp:
-            async with self._device.set_lock:
-                _LOGGER.info(
-                    "%s setting position to %d%%", self._config.config_id, position
-                )
-                await self._position_dp.async_set_value(self._device, position)
+            _LOGGER.info(
+                "%s setting position to %d%%", self._config.config_id, position
+            )
+            await self._position_dp.async_set_value(self._device, position)
         else:
             raise NotImplementedError()
 
     async def async_set_cover_tilt_position(self, tilt_position, **kwargs):
         """Set the cover tilt position."""
         if self._tiltpos_dp:
-            async with self._device.set_lock:
-                # If there is a fixed list of values, snap to the closest one
-                if self._tiltpos_dp.values(self._device):
-                    tilt_position = min(
-                        self._tiltpos_dp.values(self._device),
-                        key=lambda x: abs(x - tilt_position),
-                    )
-                elif self._tiltpos_dp.range(self._device):
-                    r = self._tiltpos_dp.range(self._device)
-                    tilt_position = percentage_to_ranged_value(r, tilt_position)
-
-                _LOGGER.info(
-                    "%s setting tilt position to %d%%",
-                    self._config.config_id,
-                    tilt_position,
+            # If there is a fixed list of values, snap to the closest one
+            if self._tiltpos_dp.values(self._device):
+                tilt_position = min(
+                    self._tiltpos_dp.values(self._device),
+                    key=lambda x: abs(x - tilt_position),
                 )
-                await self._tiltpos_dp.async_set_value(self._device, tilt_position)
+            elif self._tiltpos_dp.range(self._device):
+                r = self._tiltpos_dp.range(self._device)
+                tilt_position = percentage_to_ranged_value(r, tilt_position)
+
+            _LOGGER.info(
+                "%s setting tilt position to %d%%",
+                self._config.config_id,
+                tilt_position,
+            )
+            await self._tiltpos_dp.async_set_value(self._device, tilt_position)
         else:
             raise NotImplementedError
 
     async def async_stop_cover(self, **kwargs):
         """Stop the cover."""
         if self._control_dp and "stop" in self._control_dp.values(self._device):
-            async with self._device.set_lock:
-                _LOGGER.info("%s stopping", self._config.config_id)
-                await self._control_dp.async_set_value(self._device, "stop")
+            _LOGGER.info("%s stopping", self._config.config_id)
+            await self._control_dp.async_set_value(self._device, "stop")
         else:
             raise NotImplementedError()

+ 1 - 2
custom_components/tuya_local/datetime.py

@@ -103,8 +103,7 @@ class TuyaLocalDateTime(TuyaLocalEntity, DateTimeEntity):
 
     async def async_set_value(self, value: datetime):
         """Set the datetime."""
-        async with self._device.set_lock:
-            return await self._async_set_value_locked(value)
+        return await self._async_set_value_locked(value)
 
     async def _async_set_value_locked(self, value: datetime):
         settings = {}

+ 0 - 6
custom_components/tuya_local/device.py

@@ -160,12 +160,6 @@ class TuyaLocalDevice(object):
         # The number of failures from a working protocol before retrying other protocols.
         self._AUTO_FAILURE_RESET_COUNT = 10
         self._lock = Lock()
-        # Serialises the read-modify-write window for entities that share a
-        # packed dp (e.g. multiple sub-entity lights writing to dp 51 with
-        # different masks). Without this, two concurrent async_turn_on calls
-        # both read the same baseline before either updates pending, then the
-        # second's pending update clobbers the first.
-        self.set_lock = asyncio.Lock()
 
     @property
     def name(self):

+ 7 - 3
custom_components/tuya_local/devices/woods_cortina_airconditioner.yaml

@@ -1,8 +1,8 @@
 name: Air conditioner
 products:
-  - id: bfc0e42617f4fdfef7t6ra
-    manufacturer: Woods
-    model: Cortina Silent 12k
+  # - id: UNKNOWN
+  #   manufacturer: Woods
+  #   model: Cortina Silent 12k
 entities:
   - entity: climate
     dps:
@@ -17,12 +17,16 @@ entities:
             conditions:
               - value: cool
                 dps_val: "0"
+              - dps_val: "1"
+                value: heat_cool
+                available: airswitch
               - value: dry
                 dps_val: "2"
               - value: fan_only
                 dps_val: "3"
               - value: heat_cool
                 dps_val: "4"  # This is Woods ECO mode
+                available: eco
       - id: 2
         type: integer
         name: temperature

+ 20 - 43
custom_components/tuya_local/fan.py

@@ -88,15 +88,6 @@ class TuyaLocalFan(TuyaLocalEntity, FanEntity):
         **kwargs: Any,
     ):
         """Turn the fan on, setting any other parameters given"""
-        async with self._device.set_lock:
-            return await self._async_turn_on_locked(percentage, preset_mode, **kwargs)
-
-    async def _async_turn_on_locked(
-        self,
-        percentage: int | None,
-        preset_mode: str | None,
-        **kwargs: Any,
-    ):
         settings = {}
         if self._switch_dps:
             _LOGGER.info("%s turning on", self._config.config_id)
@@ -134,21 +125,18 @@ class TuyaLocalFan(TuyaLocalEntity, FanEntity):
 
     async def async_turn_off(self, **kwargs):
         """Turn the switch off"""
-        async with self._device.set_lock:
-            if self._switch_dps:
-                _LOGGER.info("%s turning off", self._config.config_id)
-                await self._switch_dps.async_set_value(self._device, False)
-            elif (
-                self._speed_dps
-                and self._speed_dps.range(self._device)
-                and self._speed_dps.range(self._device)[0] == 0
-            ):
-                _LOGGER.info(
-                    "%s turning off by setting speed to 0", self._config.config_id
-                )
-                await self._speed_dps.async_set_value(self._device, 0)
-            else:
-                raise NotImplementedError
+        if self._switch_dps:
+            _LOGGER.info("%s turning off", self._config.config_id)
+            await self._switch_dps.async_set_value(self._device, False)
+        elif (
+            self._speed_dps
+            and self._speed_dps.range(self._device)
+            and self._speed_dps.range(self._device)[0] == 0
+        ):
+            _LOGGER.info("%s turning off by setting speed to 0", self._config.config_id)
+            await self._speed_dps.async_set_value(self._device, 0)
+        else:
+            raise NotImplementedError
 
     @property
     def percentage(self):
@@ -185,10 +173,6 @@ class TuyaLocalFan(TuyaLocalEntity, FanEntity):
 
     async def async_set_percentage(self, percentage):
         """Set the fan speed as a percentage."""
-        async with self._device.set_lock:
-            return await self._async_set_percentage_locked(percentage)
-
-    async def _async_set_percentage_locked(self, percentage):
         # If speed is 0, turn the fan off
         if percentage == 0 and self._switch_dps:
             return await self.async_turn_off()
@@ -233,11 +217,10 @@ class TuyaLocalFan(TuyaLocalEntity, FanEntity):
         """Set the preset mode."""
         if self._preset_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting preset mode to %s", self._config.config_id, preset_mode
-            )
-            await self._preset_dps.async_set_value(self._device, preset_mode)
+        _LOGGER.info(
+            "%s setting preset mode to %s", self._config.config_id, preset_mode
+        )
+        await self._preset_dps.async_set_value(self._device, preset_mode)
 
     @property
     def current_direction(self):
@@ -249,11 +232,8 @@ class TuyaLocalFan(TuyaLocalEntity, FanEntity):
         """Set the direction of the fan."""
         if self._direction_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting direction to %s", self._config.config_id, direction
-            )
-            await self._direction_dps.async_set_value(self._device, direction)
+        _LOGGER.info("%s setting direction to %s", self._config.config_id, direction)
+        await self._direction_dps.async_set_value(self._device, direction)
 
     @property
     def oscillating(self):
@@ -265,8 +245,5 @@ class TuyaLocalFan(TuyaLocalEntity, FanEntity):
         """Oscillate the fan."""
         if self._oscillate_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting oscillate to %s", self._config.config_id, oscillating
-            )
-            await self._oscillate_dps.async_set_value(self._device, oscillating)
+        _LOGGER.info("%s setting oscillate to %s", self._config.config_id, oscillating)
+        await self._oscillate_dps.async_set_value(self._device, oscillating)

+ 8 - 12
custom_components/tuya_local/humidifier.py

@@ -99,15 +99,13 @@ class TuyaLocalHumidifier(TuyaLocalEntity, HumidifierEntity):
 
     async def async_turn_on(self, **kwargs):
         """Turn the switch on"""
-        async with self._device.set_lock:
-            _LOGGER.info("%s turning on", self._config.config_id)
-            await self._switch_dp.async_set_value(self._device, True)
+        _LOGGER.info("%s turning on", self._config.config_id)
+        await self._switch_dp.async_set_value(self._device, True)
 
     async def async_turn_off(self, **kwargs):
         """Turn the switch off"""
-        async with self._device.set_lock:
-            _LOGGER.info("%s turning off", self._config.config_id)
-            await self._switch_dp.async_set_value(self._device, False)
+        _LOGGER.info("%s turning off", self._config.config_id)
+        await self._switch_dp.async_set_value(self._device, False)
 
     @property
     def current_humidity(self):
@@ -141,9 +139,8 @@ class TuyaLocalHumidifier(TuyaLocalEntity, HumidifierEntity):
     async def async_set_humidity(self, humidity):
         if self._humidity_dp is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info("%s setting humidity to %s", self._config.config_id, humidity)
-            await self._humidity_dp.async_set_value(self._device, humidity)
+        _LOGGER.info("%s setting humidity to %s", self._config.config_id, humidity)
+        await self._humidity_dp.async_set_value(self._device, humidity)
 
     @property
     def mode(self):
@@ -162,6 +159,5 @@ class TuyaLocalHumidifier(TuyaLocalEntity, HumidifierEntity):
         """Set the preset mode."""
         if self._mode_dp is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info("%s setting mode to %s", self._config.config_id, mode)
-            await self._mode_dp.async_set_value(self._device, mode)
+        _LOGGER.info("%s setting mode to %s", self._config.config_id, mode)
+        await self._mode_dp.async_set_value(self._device, mode)

+ 9 - 10
custom_components/tuya_local/infrared.py

@@ -83,16 +83,15 @@ class TuyaLocalInfrared(TuyaLocalEntity, InfraredEntity):
     async def _ir_send(self, tuya_command: str):
         """Send the infrared command to the device."""
         if self._send_dp:
-            async with self._device.set_lock:
-                if self._command_dp:
-                    await self._device.async_set_properties(
-                        self._package_multi_dp_send(tuya_command)
-                    )
-                else:
-                    await self._send_dp.async_set_value(
-                        self._device,
-                        self._package_single_dp_send(tuya_command),
-                    )
+            if self._command_dp:
+                await self._device.async_set_properties(
+                    self._package_multi_dp_send(tuya_command)
+                )
+            else:
+                await self._send_dp.async_set_value(
+                    self._device,
+                    self._package_single_dp_send(tuya_command),
+                )
 
     def _package_single_dp_send(self, command: str) -> str:
         """Package the command for a single DP (usually dp id 201) send."""

+ 6 - 11
custom_components/tuya_local/lawn_mower.py

@@ -65,22 +65,17 @@ class TuyaLocalLawnMower(TuyaLocalEntity, LawnMowerEntity):
     async def async_start_mowing(self) -> None:
         """Start mowing the lawn."""
         if self._command_dp:
-            async with self._device.set_lock:
-                _LOGGER.info("%s starting lawn mowing", self._config.config_id)
-                await self._command_dp.async_set_value(
-                    self._device, SERVICE_START_MOWING
-                )
+            _LOGGER.info("%s starting lawn mowing", self._config.config_id)
+            await self._command_dp.async_set_value(self._device, SERVICE_START_MOWING)
 
     async def async_pause(self):
         """Pause lawn mowing."""
         if self._command_dp:
-            async with self._device.set_lock:
-                _LOGGER.info("%s pausing lawn mowing", self._config.config_id)
-                await self._command_dp.async_set_value(self._device, SERVICE_PAUSE)
+            _LOGGER.info("%s pausing lawn mowing", self._config.config_id)
+            await self._command_dp.async_set_value(self._device, SERVICE_PAUSE)
 
     async def async_dock(self):
         """Stop mowing and return to dock."""
         if self._command_dp:
-            async with self._device.set_lock:
-                _LOGGER.info("%s returning to dock", self._config.config_id)
-                await self._command_dp.async_set_value(self._device, SERVICE_DOCK)
+            _LOGGER.info("%s returning to dock", self._config.config_id)
+            await self._command_dp.async_set_value(self._device, SERVICE_DOCK)

+ 1 - 6
custom_components/tuya_local/light.py

@@ -285,10 +285,6 @@ class TuyaLocalLight(TuyaLocalEntity, LightEntity):
             return best_match
 
     async def async_turn_on(self, **params):
-        async with self._device.set_lock:
-            await self._async_turn_on_locked(**params)
-
-    async def _async_turn_on_locked(self, **params):
         settings = {}
         color_mode = None
         _LOGGER.debug("Light turn_on: %s", params)
@@ -568,8 +564,7 @@ class TuyaLocalLight(TuyaLocalEntity, LightEntity):
             await self._device.async_set_properties(settings)
 
     async def async_turn_off(self):
-        async with self._device.set_lock:
-            await self._async_turn_off_locked()
+        await self._async_turn_off_locked()
 
     async def _async_turn_off_locked(self):
         if self._switch_dps and not self._switch_dps.readonly:

+ 34 - 40
custom_components/tuya_local/lock.py

@@ -182,59 +182,53 @@ class TuyaLocalLock(TuyaLocalEntity, LockEntity):
         """Lock the lock."""
         if self._lock_dp and not self._lock_dp.readonly:
             _LOGGER.info("%s locking", self._config.config_id)
-            async with self._device.set_lock:
-                await self._lock_dp.async_set_value(self._device, True)
+            await self._lock_dp.async_set_value(self._device, True)
         elif self._code_unlock_dp:
             code = kwargs.get("code")
             if not code:
                 raise ValueError("Code required to lock")
-            async with self._device.set_lock:
-                msg = self.build_code_unlock_msg(
-                    CODE_LOCK, member_id=1, code=code, source=CODE_SRC_UNKNOWN
-                )
-                _LOGGER.info("%s locking with code", self._config.config_id)
-                await self._code_unlock_dp.async_set_value(self._device, msg)
+            msg = self.build_code_unlock_msg(
+                CODE_LOCK, member_id=1, code=code, source=CODE_SRC_UNKNOWN
+            )
+            _LOGGER.info("%s locking with code", self._config.config_id)
+            await self._code_unlock_dp.async_set_value(self._device, msg)
         else:
             raise NotImplementedError()
 
     async def async_unlock(self, **kwargs):
         """Unlock the lock."""
-        async with self._device.set_lock:
-            if self._code_unlock_dp:
-                code = kwargs.get("code")
-                if not code:
-                    raise ValueError("Code required to unlock")
-                msg = self.build_code_unlock_msg(
-                    CODE_UNLOCK, member_id=1, code=code, source=CODE_SRC_UNKNOWN
-                )
-                _LOGGER.info("%s unlocking with code", self._config.config_id)
-                await self._code_unlock_dp.async_set_value(self._device, msg)
-            elif self._lock_dp and not self._lock_dp.readonly:
-                _LOGGER.info("%s unlocking", self._config.config_id)
-                await self._lock_dp.async_set_value(self._device, False)
-            elif self._approve_unlock_dp:
-                if self._req_unlock_dp and not self._req_unlock_dp.get_value(
-                    self._device
-                ):
-                    raise TimeoutError()
-                _LOGGER.info("%s approving unlock", self._config.config_id)
-                await self._approve_unlock_dp.async_set_value(self._device, True)
-            elif self._approve_intercom_dp:
-                if self._req_intercom_dp and not self._req_intercom_dp.get_value(
-                    self._device
-                ):
-                    raise TimeoutError()
-                _LOGGER.info("%s approving intercom unlock", self._config.config_id)
-                await self._approve_intercom_dp.async_set_value(self._device, True)
-            else:
-                raise NotImplementedError()
+        if self._code_unlock_dp:
+            code = kwargs.get("code")
+            if not code:
+                raise ValueError("Code required to unlock")
+            msg = self.build_code_unlock_msg(
+                CODE_UNLOCK, member_id=1, code=code, source=CODE_SRC_UNKNOWN
+            )
+            _LOGGER.info("%s unlocking with code", self._config.config_id)
+            await self._code_unlock_dp.async_set_value(self._device, msg)
+        elif self._lock_dp and not self._lock_dp.readonly:
+            _LOGGER.info("%s unlocking", self._config.config_id)
+            await self._lock_dp.async_set_value(self._device, False)
+        elif self._approve_unlock_dp:
+            if self._req_unlock_dp and not self._req_unlock_dp.get_value(self._device):
+                raise TimeoutError()
+            _LOGGER.info("%s approving unlock", self._config.config_id)
+            await self._approve_unlock_dp.async_set_value(self._device, True)
+        elif self._approve_intercom_dp:
+            if self._req_intercom_dp and not self._req_intercom_dp.get_value(
+                self._device
+            ):
+                raise TimeoutError()
+            _LOGGER.info("%s approving intercom unlock", self._config.config_id)
+            await self._approve_intercom_dp.async_set_value(self._device, True)
+        else:
+            raise NotImplementedError()
 
     async def async_open(self, **kwargs):
         """Open the door latch."""
         if self._open_dp:
-            async with self._device.set_lock:
-                _LOGGER.info("%s opening", self._config.config_id)
-                await self._open_dp.async_set_value(self._device, True)
+            _LOGGER.info("%s opening", self._config.config_id)
+            await self._open_dp.async_set_value(self._device, True)
 
     def build_code_unlock_msg(self, action, member_id, code, source=CODE_SRC_UNKNOWN):
         """Generate the unlock code message."""

+ 13 - 14
custom_components/tuya_local/number.py

@@ -120,17 +120,16 @@ class TuyaLocalNumber(TuyaLocalEntity, NumberEntity):
 
     async def async_set_native_value(self, value):
         """Set the number."""
-        async with self._device.set_lock:
-            _LOGGER.info("%s setting value to %s", self._config.config_id, value)
-            settings = {}
-            if self._decimal_dps is not None:
-                whole = int(value)
-                decimal = value - whole
-                settings = self._decimal_dps.get_values_to_set(self._device, decimal)
-                value = whole
-
-            settings = settings | self._value_dps.get_values_to_set(
-                self._device, value, settings
-            )
-
-            await self._device.async_set_properties(settings)
+        _LOGGER.info("%s setting value to %s", self._config.config_id, value)
+        settings = {}
+        if self._decimal_dps is not None:
+            whole = int(value)
+            decimal = value - whole
+            settings = self._decimal_dps.get_values_to_set(self._device, decimal)
+            value = whole
+
+        settings = settings | self._value_dps.get_values_to_set(
+            self._device, value, settings
+        )
+
+        await self._device.async_set_properties(settings)

+ 48 - 53
custom_components/tuya_local/remote.py

@@ -271,21 +271,18 @@ class TuyaLocalRemote(TuyaLocalEntity, RemoteEntity):
             else:
                 code = codes[0]
 
-            async with self._device.set_lock:
-                # Tuya delay is in milliseconds
-                if code.startswith("rf:"):
-                    dps_to_set = self._encode_send_code(
-                        code[3:], delay * 1000, is_rf=True
-                    )
-                else:
-                    dps_to_set = self._encode_send_code(code, delay * 1000)
-                    _LOGGER.info(
-                        "%s sending command %s to %s",
-                        self._config.config_id,
-                        code,
-                        subdevice or "default device",
-                    )
-                    await self._device.async_set_properties(dps_to_set)
+            # Tuya delay is in milliseconds
+            if code.startswith("rf:"):
+                dps_to_set = self._encode_send_code(code[3:], delay * 1000, is_rf=True)
+            else:
+                dps_to_set = self._encode_send_code(code, delay * 1000)
+                _LOGGER.info(
+                    "%s sending command %s to %s",
+                    self._config.config_id,
+                    code,
+                    subdevice or "default device",
+                )
+                await self._device.async_set_properties(dps_to_set)
 
             if len(codes) > 1:
                 self._flags[subdevice] ^= 1
@@ -339,31 +336,30 @@ class TuyaLocalRemote(TuyaLocalEntity, RemoteEntity):
                     "ver": "2",
                 }
             )
-        async with self._device.set_lock:
-            if self._control_dp:
-                _LOGGER.debug(
-                    "%s starting learning %s using multi dps method",
-                    self._config.config_id,
-                    command,
-                )
-                await self._control_dp.async_set_value(self._device, CMD_LEARN)
-            elif is_rf:
-                _LOGGER.debug(
-                    "%s starting learning %s using RF",
-                    self._config.config_id,
-                    command,
-                )
-                await self._send_dp.async_set_value(self._device, cmd_start)
-            else:
-                _LOGGER.debug(
-                    "%s starting learning %s using IR",
-                    self._config.config_id,
-                    command,
-                )
-                await self._send_dp.async_set_value(
-                    self._device,
-                    json.dumps({"control": CMD_LEARN}),
-                )
+        if self._control_dp:
+            _LOGGER.debug(
+                "%s starting learning %s using multi dps method",
+                self._config.config_id,
+                command,
+            )
+            await self._control_dp.async_set_value(self._device, CMD_LEARN)
+        elif is_rf:
+            _LOGGER.debug(
+                "%s starting learning %s using RF",
+                self._config.config_id,
+                command,
+            )
+            await self._send_dp.async_set_value(self._device, cmd_start)
+        else:
+            _LOGGER.debug(
+                "%s starting learning %s using IR",
+                self._config.config_id,
+                command,
+            )
+            await self._send_dp.async_set_value(
+                self._device,
+                json.dumps({"control": CMD_LEARN}),
+            )
 
         persistent_notification.async_create(
             self._device._hass,
@@ -395,19 +391,18 @@ class TuyaLocalRemote(TuyaLocalEntity, RemoteEntity):
                 self._device._hass, notification_id="learn_command"
             )
             _LOGGER.debug("%s ending learning mode", self._config.config_id)
-            async with self._device.set_lock:
-                if self._control_dp:
-                    await self._control_dp.async_set_value(
-                        self._device,
-                        CMD_ENDLEARN,
-                    )
-                elif is_rf:
-                    await self._send_dp.async_set_value(self._device, cmd_end)
-                else:
-                    await self._send_dp.async_set_value(
-                        self._device,
-                        json.dumps({"control": CMD_ENDLEARN}),
-                    )
+            if self._control_dp:
+                await self._control_dp.async_set_value(
+                    self._device,
+                    CMD_ENDLEARN,
+                )
+            elif is_rf:
+                await self._send_dp.async_set_value(self._device, cmd_end)
+            else:
+                await self._send_dp.async_set_value(
+                    self._device,
+                    json.dumps({"control": CMD_ENDLEARN}),
+                )
 
     async def async_delete_command(self, **kwargs: Any) -> None:
         """Delete a list of commands from a remote."""

+ 2 - 3
custom_components/tuya_local/select.py

@@ -58,6 +58,5 @@ class TuyaLocalSelect(TuyaLocalEntity, SelectEntity):
 
     async def async_select_option(self, option):
         "Set the option"
-        async with self._device.set_lock:
-            _LOGGER.info("%s selecting option %s", self._config.config_id, option)
-            await self._option_dps.async_set_value(self._device, option)
+        _LOGGER.info("%s selecting option %s", self._config.config_id, option)
+        await self._option_dps.async_set_value(self._device, option)

+ 7 - 9
custom_components/tuya_local/siren.py

@@ -79,8 +79,7 @@ class TuyaLocalSiren(TuyaLocalEntity, SirenEntity):
             return self._tone_dp.get_value(self._device) != "off"
 
     async def async_turn_on(self, **kwargs) -> None:
-        async with self._device.set_lock:
-            await self._async_turn_on_locked(**kwargs)
+        await self._async_turn_on_locked(**kwargs)
 
     async def _async_turn_on_locked(self, **kwargs) -> None:
         tone = kwargs.get(ATTR_TONE, None)
@@ -137,10 +136,9 @@ class TuyaLocalSiren(TuyaLocalEntity, SirenEntity):
 
     async def async_turn_off(self) -> None:
         """Turn off the siren"""
-        async with self._device.set_lock:
-            if self._switch_dp:
-                _LOGGER.info("%s turning off siren", self._config.config_id)
-                await self._switch_dp.async_set_value(self._device, False)
-            elif self._tone_dp:
-                _LOGGER.info("%s setting siren tone to off", self._config.config_id)
-                await self._tone_dp.async_set_value(self._device, "off")
+        if self._switch_dp:
+            _LOGGER.info("%s turning off siren", self._config.config_id)
+            await self._switch_dp.async_set_value(self._device, False)
+        elif self._tone_dp:
+            _LOGGER.info("%s setting siren tone to off", self._config.config_id)
+            await self._tone_dp.async_set_value(self._device, "off")

+ 4 - 6
custom_components/tuya_local/switch.py

@@ -64,12 +64,10 @@ class TuyaLocalSwitch(TuyaLocalEntity, SwitchEntity):
 
     async def async_turn_on(self, **kwargs):
         """Turn the switch on"""
-        async with self._device.set_lock:
-            _LOGGER.info("%s turning on", self._config.config_id)
-            await self._switch_dps.async_set_value(self._device, True)
+        _LOGGER.info("%s turning on", self._config.config_id)
+        await self._switch_dps.async_set_value(self._device, True)
 
     async def async_turn_off(self, **kwargs):
         """Turn the switch off"""
-        async with self._device.set_lock:
-            _LOGGER.info("%s turning off", self._config.config_id)
-            await self._switch_dps.async_set_value(self._device, False)
+        _LOGGER.info("%s turning off", self._config.config_id)
+        await self._switch_dps.async_set_value(self._device, False)

+ 2 - 3
custom_components/tuya_local/text.py

@@ -75,9 +75,8 @@ class TuyaLocalText(TuyaLocalEntity, TextEntity):
 
     async def async_set_value(self, value: str) -> None:
         """Set the value"""
-        async with self._device.set_lock:
-            _LOGGER.info("%s setting value to %s", self._config.config_id, value)
-            await self._value_dp.async_set_value(self._device, value)
+        _LOGGER.info("%s setting value to %s", self._config.config_id, value)
+        await self._value_dp.async_set_value(self._device, value)
 
     @property
     def extra_state_attributes(self) -> dict[str, any]:

+ 1 - 2
custom_components/tuya_local/time.py

@@ -99,8 +99,7 @@ class TuyaLocalTime(TuyaLocalEntity, TimeEntity):
 
     async def async_set_value(self, value: time):
         """Set the number."""
-        async with self._device.set_lock:
-            return await self._async_set_value_locked(value)
+        return await self._async_set_value_locked(value)
 
     async def _async_set_value_locked(self, value: time):
         settings = {}

+ 44 - 55
custom_components/tuya_local/vacuum.py

@@ -120,77 +120,68 @@ class TuyaLocalVacuum(TuyaLocalEntity, StateVacuumEntity):
     async def async_turn_on(self, **kwargs):
         """Turn on the vacuum cleaner."""
         if self._power_dps:
-            async with self._device.set_lock:
-                _LOGGER.info("%s turning on", self._config.config_id)
-                await self._power_dps.async_set_value(self._device, True)
+            _LOGGER.info("%s turning on", self._config.config_id)
+            await self._power_dps.async_set_value(self._device, True)
 
     async def async_turn_off(self, **kwargs):
         """Turn off the vacuum cleaner."""
         if self._power_dps:
-            async with self._device.set_lock:
-                _LOGGER.info("%s turning off", self._config.config_id)
-                await self._power_dps.async_set_value(self._device, False)
+            _LOGGER.info("%s turning off", self._config.config_id)
+            await self._power_dps.async_set_value(self._device, False)
 
     async def async_toggle(self, **kwargs):
         """Toggle the vacuum cleaner."""
         dps = self._power_dps or self._activate_dps
         if dps:
-            async with self._device.set_lock:
-                switch_to = not dps.get_value(self._device)
-                _LOGGER.info("%s toggling to %s", self._config.config_id, switch_to)
-                await dps.async_set_value(self._device, switch_to)
+            switch_to = not dps.get_value(self._device)
+            _LOGGER.info("%s toggling to %s", self._config.config_id, switch_to)
+            await dps.async_set_value(self._device, switch_to)
 
     async def async_start(self):
         dps = self._command_dps or self._status_dps
-        async with self._device.set_lock:
-            if dps and "start" in dps.values(self._device):
-                _LOGGER.info("%s starting by command", self._config.config_id)
-                await dps.async_set_value(self._device, "start")
-            elif self._activate_dps:
-                _LOGGER.info("%s activating", self._config.config_id)
-                await self._activate_dps.async_set_value(self._device, True)
+        if dps and "start" in dps.values(self._device):
+            _LOGGER.info("%s starting by command", self._config.config_id)
+            await dps.async_set_value(self._device, "start")
+        elif self._activate_dps:
+            _LOGGER.info("%s activating", self._config.config_id)
+            await self._activate_dps.async_set_value(self._device, True)
 
     async def async_pause(self):
         """Pause the vacuum cleaner."""
         dps = self._command_dps or self._status_dps
-        async with self._device.set_lock:
-            if dps and "pause" in dps.values(self._device):
-                _LOGGER.info("%s pausing by command", self._config.config_id)
-                await dps.async_set_value(self._device, "pause")
-            elif self._activate_dps:
-                _LOGGER.info("%s deactivating", self._config.config_id)
-                await self._activate_dps.async_set_value(self._device, False)
+        if dps and "pause" in dps.values(self._device):
+            _LOGGER.info("%s pausing by command", self._config.config_id)
+            await dps.async_set_value(self._device, "pause")
+        elif self._activate_dps:
+            _LOGGER.info("%s deactivating", self._config.config_id)
+            await self._activate_dps.async_set_value(self._device, False)
 
     async def async_return_to_base(self, **kwargs):
         """Tell the vacuum cleaner to return to its base."""
         dps = self._command_dps or self._status_dps
         if dps and SERVICE_RETURN_TO_BASE in dps.values(self._device):
-            async with self._device.set_lock:
-                _LOGGER.info("%s returning to base", self._config.config_id)
-                await dps.async_set_value(self._device, SERVICE_RETURN_TO_BASE)
+            _LOGGER.info("%s returning to base", self._config.config_id)
+            await dps.async_set_value(self._device, SERVICE_RETURN_TO_BASE)
 
     async def async_clean_spot(self, **kwargs):
         """Tell the vacuum cleaner do a spot clean."""
         dps = self._command_dps or self._status_dps
         if dps and SERVICE_CLEAN_SPOT in dps.values(self._device):
-            async with self._device.set_lock:
-                _LOGGER.info("%s doing spot clean", self._config.config_id)
-                await dps.async_set_value(self._device, SERVICE_CLEAN_SPOT)
+            _LOGGER.info("%s doing spot clean", self._config.config_id)
+            await dps.async_set_value(self._device, SERVICE_CLEAN_SPOT)
 
     async def async_stop(self, **kwargs):
         """Tell the vacuum cleaner to stop."""
         dps = self._command_dps or self._status_dps
         if dps and SERVICE_STOP in dps.values(self._device):
-            async with self._device.set_lock:
-                _LOGGER.info("%s stopping", self._config.config_id)
-                await dps.async_set_value(self._device, SERVICE_STOP)
+            _LOGGER.info("%s stopping", self._config.config_id)
+            await dps.async_set_value(self._device, SERVICE_STOP)
 
     async def async_locate(self, **kwargs):
         """Locate the vacuum cleaner."""
         if self._locate_dps:
-            async with self._device.set_lock:
-                _LOGGER.info("%s locating", self._config.config_id)
-                await self._locate_dps.async_set_value(self._device, True)
+            _LOGGER.info("%s locating", self._config.config_id)
+            await self._locate_dps.async_set_value(self._device, True)
 
     async def async_send_command(self, command, params=None, **kwargs):
         """Send a command to the vacuum cleaner."""
@@ -205,20 +196,19 @@ class TuyaLocalVacuum(TuyaLocalEntity, StateVacuumEntity):
         ):
             dps = self._direction_dps
 
-        async with self._device.set_lock:
-            if command in dps.values(self._device):
-                _LOGGER.info(
-                    "%s sending %s %s",
-                    self._config.config_id,
-                    "direction" if dps is self._direction_dps else "command",
-                    command,
-                )
-                await dps.async_set_value(self._device, command)
-            elif self._direction_dps and command in self._direction_dps.values(
-                self._device
-            ):
-                _LOGGER.info("%s sending direction %s", self._config.config_id, command)
-                await self._direction_dps.async_set_value(self._device, command)
+        if command in dps.values(self._device):
+            _LOGGER.info(
+                "%s sending %s %s",
+                self._config.config_id,
+                "direction" if dps is self._direction_dps else "command",
+                command,
+            )
+            await dps.async_set_value(self._device, command)
+        elif self._direction_dps and command in self._direction_dps.values(
+            self._device
+        ):
+            _LOGGER.info("%s sending direction %s", self._config.config_id, command)
+            await self._direction_dps.async_set_value(self._device, command)
 
     @property
     def fan_speed_list(self):
@@ -235,8 +225,7 @@ class TuyaLocalVacuum(TuyaLocalEntity, StateVacuumEntity):
     async def async_set_fan_speed(self, fan_speed, **kwargs):
         """Set the fan speed of the vacuum."""
         if self._fan_dps:
-            async with self._device.set_lock:
-                _LOGGER.info(
-                    "%s setting fan speed to %s", self._config.config_id, fan_speed
-                )
-                await self._fan_dps.async_set_value(self._device, fan_speed)
+            _LOGGER.info(
+                "%s setting fan speed to %s", self._config.config_id, fan_speed
+            )
+            await self._fan_dps.async_set_value(self._device, fan_speed)

+ 14 - 16
custom_components/tuya_local/valve.py

@@ -101,17 +101,16 @@ class TuyaLocalValve(TuyaLocalEntity, ValveEntity):
 
     async def async_open_valve(self):
         """Open the valve."""
-        async with self._device.set_lock:
-            if self._switch_dp:
-                _LOGGER.info("%s opening valve", self._config.config_id)
-                await self._switch_dp.async_set_value(self._device, True)
-                if self._valve_dp.get_value(self._device):
-                    return
-            _LOGGER.info("%s fully opening valve", self._config.config_id)
-            await self._valve_dp.async_set_value(
-                self._device,
-                100 if self.reports_position else True,
-            )
+        if self._switch_dp:
+            _LOGGER.info("%s opening valve", self._config.config_id)
+            await self._switch_dp.async_set_value(self._device, True)
+            if self._valve_dp.get_value(self._device):
+                return
+        _LOGGER.info("%s fully opening valve", self._config.config_id)
+        await self._valve_dp.async_set_value(
+            self._device,
+            100 if self.reports_position else True,
+        )
 
     async def async_close_valve(self):
         """Close the valve"""
@@ -129,8 +128,7 @@ class TuyaLocalValve(TuyaLocalEntity, ValveEntity):
         """Set the position of the valve"""
         if not self.reports_position:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting valve position to %s%%", self._config.config_id, position
-            )
-            await self._valve_dp.async_set_value(self._device, position)
+        _LOGGER.info(
+            "%s setting valve position to %s%%", self._config.config_id, position
+        )
+        await self._valve_dp.async_set_value(self._device, position)

+ 31 - 37
custom_components/tuya_local/water_heater.py

@@ -187,37 +187,34 @@ class TuyaLocalWaterHeater(TuyaLocalEntity, WaterHeaterEntity):
         if kwargs.get(ATTR_TEMPERATURE) is not None:
             if self._temperature_dps is None:
                 raise NotImplementedError()
-            async with self._device.set_lock:
-                _LOGGER.info(
-                    "%s setting temperature to %s",
-                    self._config.config_id,
-                    kwargs.get(ATTR_TEMPERATURE),
-                )
-                await self._temperature_dps.async_set_value(
-                    self._device, kwargs.get(ATTR_TEMPERATURE)
-                )
+            _LOGGER.info(
+                "%s setting temperature to %s",
+                self._config.config_id,
+                kwargs.get(ATTR_TEMPERATURE),
+            )
+            await self._temperature_dps.async_set_value(
+                self._device, kwargs.get(ATTR_TEMPERATURE)
+            )
 
     async def async_set_operation_mode(self, operation_mode):
         """Set new target operation mode."""
         if self._operation_mode_dps is None:
             raise NotImplementedError()
-        async with self._device.set_lock:
-            _LOGGER.info(
-                "%s setting operation mode to %s",
-                self._config.config_id,
-                operation_mode,
-            )
-            await self._operation_mode_dps.async_set_value(
-                self._device,
-                operation_mode,
-            )
+        _LOGGER.info(
+            "%s setting operation mode to %s",
+            self._config.config_id,
+            operation_mode,
+        )
+        await self._operation_mode_dps.async_set_value(
+            self._device,
+            operation_mode,
+        )
 
     async def async_turn_away_mode_on(self):
         """Turn away mode on"""
         if self._away_mode_dps:
-            async with self._device.set_lock:
-                _LOGGER.info("%s turning away mode on", self._config.config_id)
-                await self._away_mode_dps.async_set_value(self._device, True)
+            _LOGGER.info("%s turning away mode on", self._config.config_id)
+            await self._away_mode_dps.async_set_value(self._device, True)
         elif self._operation_mode_dps and (
             "away" in self._operation_mode_dps.values(self._device)
         ):
@@ -232,9 +229,8 @@ class TuyaLocalWaterHeater(TuyaLocalEntity, WaterHeaterEntity):
     async def async_turn_away_mode_off(self):
         """Turn away mode off"""
         if self._away_mode_dps:
-            async with self._device.set_lock:
-                _LOGGER.info("%s turning away mode off", self._config.config_id)
-                await self._away_mode_dps.async_set_value(self._device, False)
+            _LOGGER.info("%s turning away mode off", self._config.config_id)
+            await self._away_mode_dps.async_set_value(self._device, False)
         elif self._operation_mode_dps and (
             "away" in self._operation_mode_dps.values(self._device)
         ):
@@ -274,12 +270,11 @@ class TuyaLocalWaterHeater(TuyaLocalEntity, WaterHeaterEntity):
         boolean dp.
         """
         if self._operation_mode_dps and self._operation_mode_dps.type is bool:
-            async with self._device.set_lock:
-                _LOGGER.info("%s turning on", self._config.config_id)
-                await self._device.async_set_property(
-                    self._operation_mode_dps.id,
-                    True,
-                )
+            _LOGGER.info("%s turning on", self._config.config_id)
+            await self._device.async_set_property(
+                self._operation_mode_dps.id,
+                True,
+            )
 
     async def async_turn_off(self):
         """
@@ -287,9 +282,8 @@ class TuyaLocalWaterHeater(TuyaLocalEntity, WaterHeaterEntity):
         boolean dp.
         """
         if self._operation_mode_dps and self._operation_mode_dps.type is bool:
-            async with self._device.set_lock:
-                _LOGGER.info("%s turning off", self._config.config_id)
-                await self._device.async_set_property(
-                    self._operation_mode_dps.id,
-                    False,
-                )
+            _LOGGER.info("%s turning off", self._config.config_id)
+            await self._device.async_set_property(
+                self._operation_mode_dps.id,
+                False,
+            )