From 9fb5bceeef6434b35969d6f53d6ae310738fa4a9 Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Tue, 24 Mar 2026 15:09:47 +0100 Subject: [PATCH] Migrate Tuya humidifier to TuyaHumidifierDefinition (#166340) --- homeassistant/components/tuya/humidifier.py | 83 +++++++-------------- 1 file changed, 27 insertions(+), 56 deletions(-) diff --git a/homeassistant/components/tuya/humidifier.py b/homeassistant/components/tuya/humidifier.py index 6b38edee7da..1ab7418666d 100644 --- a/homeassistant/components/tuya/humidifier.py +++ b/homeassistant/components/tuya/humidifier.py @@ -5,12 +5,10 @@ from __future__ import annotations from dataclasses import dataclass from typing import Any -from tuya_device_handlers.device_wrapper.base import DeviceWrapper -from tuya_device_handlers.device_wrapper.common import ( - DPCodeBooleanWrapper, - DPCodeEnumWrapper, +from tuya_device_handlers.definition.humidifier import ( + TuyaHumidifierDefinition, + get_default_definition, ) -from tuya_device_handlers.device_wrapper.extended import DPCodeRoundedIntegerWrapper from tuya_sharing import CustomerDevice, Manager from homeassistant.components.humidifier import ( @@ -26,7 +24,7 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback from . import TuyaConfigEntry from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode from .entity import TuyaEntity -from .util import ActionDPCodeNotFoundError, get_dpcode +from .util import ActionDPCodeNotFoundError @dataclass(frozen=True) @@ -40,20 +38,6 @@ class TuyaHumidifierEntityDescription(HumidifierEntityDescription): humidity: DPCode | None = None -def _has_a_valid_dpcode( - device: CustomerDevice, description: TuyaHumidifierEntityDescription -) -> bool: - """Check if the device has at least one valid DP code.""" - properties_to_check: list[str | tuple[str, ...] | None] = [ - # Main control switch - description.dpcode or description.key, - # Other humidity properties - description.current_humidity, - description.humidity, - ] - return any(get_dpcode(device, code) for code in properties_to_check) - - HUMIDIFIERS: dict[DeviceCategory, TuyaHumidifierEntityDescription] = { DeviceCategory.CS: TuyaHumidifierEntityDescription( key=DPCode.SWITCH, @@ -86,29 +70,16 @@ async def async_setup_entry( entities: list[TuyaHumidifierEntity] = [] for device_id in device_ids: device = manager.device_map[device_id] - if ( - description := HUMIDIFIERS.get(device.category) - ) and _has_a_valid_dpcode(device, description): + if (description := HUMIDIFIERS.get(device.category)) and ( + definition := get_default_definition( + device, + switch_dpcode=description.dpcode or description.key, + current_humidity_dpcode=description.current_humidity, + humidity_dpcode=description.humidity, + ) + ): entities.append( - TuyaHumidifierEntity( - device, - manager, - description, - current_humidity_wrapper=DPCodeRoundedIntegerWrapper.find_dpcode( - device, description.current_humidity - ), - mode_wrapper=DPCodeEnumWrapper.find_dpcode( - device, DPCode.MODE, prefer_function=True - ), - switch_wrapper=DPCodeBooleanWrapper.find_dpcode( - device, - description.dpcode or description.key, - prefer_function=True, - ), - target_humidity_wrapper=DPCodeRoundedIntegerWrapper.find_dpcode( - device, description.humidity, prefer_function=True - ), - ) + TuyaHumidifierEntity(device, manager, description, definition) ) async_add_entities(entities) @@ -130,29 +101,29 @@ class TuyaHumidifierEntity(TuyaEntity, HumidifierEntity): device: CustomerDevice, device_manager: Manager, description: TuyaHumidifierEntityDescription, - *, - current_humidity_wrapper: DeviceWrapper[int] | None = None, - mode_wrapper: DeviceWrapper[str] | None = None, - switch_wrapper: DeviceWrapper[bool] | None = None, - target_humidity_wrapper: DeviceWrapper[int] | None = None, + definition: TuyaHumidifierDefinition, ) -> None: """Init Tuya (de)humidifier.""" super().__init__(device, device_manager, description) - self._current_humidity_wrapper = current_humidity_wrapper - self._mode_wrapper = mode_wrapper - self._switch_wrapper = switch_wrapper - self._target_humidity_wrapper = target_humidity_wrapper + self._current_humidity_wrapper = definition.current_humidity_wrapper + self._mode_wrapper = definition.mode_wrapper + self._switch_wrapper = definition.switch_wrapper + self._target_humidity_wrapper = definition.target_humidity_wrapper # Determine humidity parameters - if target_humidity_wrapper: - self._attr_min_humidity = round(target_humidity_wrapper.min_value) - self._attr_max_humidity = round(target_humidity_wrapper.max_value) + if definition.target_humidity_wrapper: + self._attr_min_humidity = round( + definition.target_humidity_wrapper.min_value + ) + self._attr_max_humidity = round( + definition.target_humidity_wrapper.max_value + ) # Determine mode support and provided modes - if mode_wrapper: + if definition.mode_wrapper: self._attr_supported_features |= HumidifierEntityFeature.MODES - self._attr_available_modes = mode_wrapper.options + self._attr_available_modes = definition.mode_wrapper.options @property def is_on(self) -> bool | None: