diff --git a/homeassistant/components/tuya/cover.py b/homeassistant/components/tuya/cover.py index 09ae829f382..fd1f2aae972 100644 --- a/homeassistant/components/tuya/cover.py +++ b/homeassistant/components/tuya/cover.py @@ -36,7 +36,7 @@ class TuyaCoverEntityDescription(CoverEntityDescription): current_state: DPCode | None = None current_state_inverse: bool = False - current_position: DPCode | None = None + current_position: DPCode | tuple[DPCode, ...] | None = None set_position: DPCode | None = None @@ -49,7 +49,7 @@ COVERS: dict[str, tuple[TuyaCoverEntityDescription, ...]] = { key=DPCode.CONTROL, name="Curtain", current_state=DPCode.SITUATION_SET, - current_position=DPCode.PERCENT_STATE, + current_position=(DPCode.PERCENT_CONTROL, DPCode.PERCENT_STATE), set_position=DPCode.PERCENT_CONTROL, device_class=CoverDeviceClass.CURTAIN, ), @@ -173,6 +173,7 @@ class TuyaCoverEntity(TuyaEntity, CoverEntity): _set_position_type: IntegerTypeData | None = None _tilt_dpcode: DPCode | None = None _tilt_type: IntegerTypeData | None = None + _position_dpcode: DPCode | None = None entity_description: TuyaCoverEntityDescription def __init__( @@ -235,21 +236,34 @@ class TuyaCoverEntity(TuyaEntity, CoverEntity): device.status_range[tilt_dpcode].values ) + # Determine current_position DPCodes + if ( + self.entity_description.current_position is None + and self.entity_description.set_position is not None + ): + self._position_dpcode = self.entity_description.set_position + elif isinstance(self.entity_description.current_position, DPCode): + self._position_dpcode = self.entity_description.current_position + elif isinstance(self.entity_description.current_position, tuple): + self._position_dpcode = next( + ( + dpcode + for dpcode in self.entity_description.current_position + if self.device.status.get(dpcode) is not None + ), + None, + ) + @property def current_cover_position(self) -> int | None: """Return cover current position.""" if self._current_position_type is None: return None - if not ( - dpcode := ( - self.entity_description.current_position - or self.entity_description.set_position - ) - ): + if not self._position_dpcode: return None - if (position := self.device.status.get(dpcode)) is None: + if (position := self.device.status.get(self._position_dpcode)) is None: return None return round( @@ -296,14 +310,40 @@ class TuyaCoverEntity(TuyaEntity, CoverEntity): value: bool | str = True if self.device.function[self.entity_description.key].type == "Enum": value = "open" - self._send_command([{"code": self.entity_description.key, "value": value}]) + + commands: list[dict[str, str | int]] = [ + {"code": self.entity_description.key, "value": value} + ] + + if (self.entity_description.set_position) is not None: + commands.append( + { + "code": self.entity_description.set_position, + "value": 0, + } + ) + + self._send_command(commands) def close_cover(self, **kwargs: Any) -> None: """Close cover.""" value: bool | str = True if self.device.function[self.entity_description.key].type == "Enum": value = "close" - self._send_command([{"code": self.entity_description.key, "value": value}]) + + commands: list[dict[str, str | int]] = [ + {"code": self.entity_description.key, "value": value} + ] + + if (self.entity_description.set_position) is not None: + commands.append( + { + "code": self.entity_description.set_position, + "value": 100, + } + ) + + self._send_command(commands) def set_cover_position(self, **kwargs: Any) -> None: """Move the cover to a specific position."""