diff --git a/homeassistant/components/tuya/fan.py b/homeassistant/components/tuya/fan.py index fba42ad76cf..12b6b11a297 100644 --- a/homeassistant/components/tuya/fan.py +++ b/homeassistant/components/tuya/fan.py @@ -26,6 +26,16 @@ from .entity import TuyaEntity from .models import EnumTypeData, IntegerTypeData from .util import get_dpcode +_DIRECTION_DPCODES = (DPCode.FAN_DIRECTION,) +_OSCILLATE_DPCODES = (DPCode.SWITCH_HORIZONTAL, DPCode.SWITCH_VERTICAL) +_SPEED_DPCODES = ( + DPCode.FAN_SPEED_PERCENT, + DPCode.FAN_SPEED, + DPCode.SPEED, + DPCode.FAN_SPEED_ENUM, +) +_SWITCH_DPCODES = (DPCode.SWITCH_FAN, DPCode.FAN_SWITCH, DPCode.SWITCH) + TUYA_SUPPORT_TYPE = { # Dehumidifier # https://developer.tuya.com/en/docs/iot/categorycs?id=Kaiuz1vcz4dha @@ -47,6 +57,19 @@ TUYA_SUPPORT_TYPE = { } +def _has_a_valid_dpcode(device: CustomerDevice) -> bool: + """Check if the device has at least one valid DP code.""" + properties_to_check: list[DPCode | tuple[DPCode, ...] | None] = [ + # Main control switch + _SWITCH_DPCODES, + # Other properties + _SPEED_DPCODES, + _OSCILLATE_DPCODES, + _DIRECTION_DPCODES, + ] + return any(get_dpcode(device, code) for code in properties_to_check) + + async def async_setup_entry( hass: HomeAssistant, entry: TuyaConfigEntry, @@ -61,7 +84,7 @@ async def async_setup_entry( entities: list[TuyaFanEntity] = [] for device_id in device_ids: device = hass_data.manager.device_map[device_id] - if device and device.category in TUYA_SUPPORT_TYPE: + if device.category in TUYA_SUPPORT_TYPE and _has_a_valid_dpcode(device): entities.append(TuyaFanEntity(device, hass_data.manager)) async_add_entities(entities) @@ -91,9 +114,7 @@ class TuyaFanEntity(TuyaEntity, FanEntity): """Init Tuya Fan Device.""" super().__init__(device, device_manager) - self._switch = get_dpcode( - self.device, (DPCode.SWITCH_FAN, DPCode.FAN_SWITCH, DPCode.SWITCH) - ) + self._switch = get_dpcode(self.device, _SWITCH_DPCODES) self._attr_preset_modes = [] if enum_type := self.find_dpcode( @@ -104,31 +125,23 @@ class TuyaFanEntity(TuyaEntity, FanEntity): self._attr_preset_modes = enum_type.range # Find speed controls, can be either percentage or a set of speeds - dpcodes = ( - DPCode.FAN_SPEED_PERCENT, - DPCode.FAN_SPEED, - DPCode.SPEED, - DPCode.FAN_SPEED_ENUM, - ) if int_type := self.find_dpcode( - dpcodes, dptype=DPType.INTEGER, prefer_function=True + _SPEED_DPCODES, dptype=DPType.INTEGER, prefer_function=True ): self._attr_supported_features |= FanEntityFeature.SET_SPEED self._speed = int_type elif enum_type := self.find_dpcode( - dpcodes, dptype=DPType.ENUM, prefer_function=True + _SPEED_DPCODES, dptype=DPType.ENUM, prefer_function=True ): self._attr_supported_features |= FanEntityFeature.SET_SPEED self._speeds = enum_type - if dpcode := get_dpcode( - self.device, (DPCode.SWITCH_HORIZONTAL, DPCode.SWITCH_VERTICAL) - ): + if dpcode := get_dpcode(self.device, _OSCILLATE_DPCODES): self._oscillate = dpcode self._attr_supported_features |= FanEntityFeature.OSCILLATE if enum_type := self.find_dpcode( - DPCode.FAN_DIRECTION, dptype=DPType.ENUM, prefer_function=True + _DIRECTION_DPCODES, dptype=DPType.ENUM, prefer_function=True ): self._direction = enum_type self._attr_supported_features |= FanEntityFeature.DIRECTION diff --git a/tests/components/tuya/snapshots/test_fan.ambr b/tests/components/tuya/snapshots/test_fan.ambr index 1474aa7cccd..005420c205c 100644 --- a/tests/components/tuya/snapshots/test_fan.ambr +++ b/tests/components/tuya/snapshots/test_fan.ambr @@ -204,126 +204,26 @@ 'platform': 'tuya', 'previous_unique_id': None, 'suggested_object_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'tuya.ilms5pwjzzsxuxmvsc', - 'unit_of_measurement': None, - }) -# --- -# name: test_platform_setup_and_discovery[fan.dehumidifier-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'Dehumidifier ', - 'supported_features': , - }), - 'context': , - 'entity_id': 'fan.dehumidifier', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- -# name: test_platform_setup_and_discovery[fan.dehumidifier_2-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'fan', - 'entity_category': None, - 'entity_id': 'fan.dehumidifier_2', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': None, - 'original_icon': None, - 'original_name': None, - 'platform': 'tuya', - 'previous_unique_id': None, - 'suggested_object_id': None, 'supported_features': , 'translation_key': None, 'unique_id': 'tuya.2myxayqtud9aqbizsc', 'unit_of_measurement': None, }) # --- -# name: test_platform_setup_and_discovery[fan.dehumidifier_2-state] +# name: test_platform_setup_and_discovery[fan.dehumidifier-state] StateSnapshot({ 'attributes': ReadOnlyDict({ 'friendly_name': 'Dehumidifier', 'supported_features': , }), 'context': , - 'entity_id': 'fan.dehumidifier_2', + 'entity_id': 'fan.dehumidifier', 'last_changed': , 'last_reported': , 'last_updated': , 'state': 'on', }) # --- -# name: test_platform_setup_and_discovery[fan.dryfix-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'fan', - 'entity_category': None, - 'entity_id': 'fan.dryfix', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': None, - 'original_icon': None, - 'original_name': None, - 'platform': 'tuya', - 'previous_unique_id': None, - 'suggested_object_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'tuya.hz4pau766eavmxhqsc', - 'unit_of_measurement': None, - }) -# --- -# name: test_platform_setup_and_discovery[fan.dryfix-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'DryFix', - 'supported_features': , - }), - 'context': , - 'entity_id': 'fan.dryfix', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unavailable', - }) -# --- # name: test_platform_setup_and_discovery[fan.hl400-entry] EntityRegistryEntrySnapshot({ 'aliases': set({ @@ -556,53 +456,3 @@ 'state': 'off', }) # --- -# name: test_platform_setup_and_discovery[fan.ventilador_cama-entry] - EntityRegistryEntrySnapshot({ - 'aliases': set({ - }), - 'area_id': None, - 'capabilities': dict({ - }), - 'config_entry_id': , - 'config_subentry_id': , - 'device_class': None, - 'device_id': , - 'disabled_by': None, - 'domain': 'fan', - 'entity_category': None, - 'entity_id': 'fan.ventilador_cama', - 'has_entity_name': True, - 'hidden_by': None, - 'icon': None, - 'id': , - 'labels': set({ - }), - 'name': None, - 'options': dict({ - }), - 'original_device_class': None, - 'original_icon': None, - 'original_name': None, - 'platform': 'tuya', - 'previous_unique_id': None, - 'suggested_object_id': None, - 'supported_features': 0, - 'translation_key': None, - 'unique_id': 'tuya.c1tfgunpf6optybisf', - 'unit_of_measurement': None, - }) -# --- -# name: test_platform_setup_and_discovery[fan.ventilador_cama-state] - StateSnapshot({ - 'attributes': ReadOnlyDict({ - 'friendly_name': 'Ventilador Cama', - 'supported_features': , - }), - 'context': , - 'entity_id': 'fan.ventilador_cama', - 'last_changed': , - 'last_reported': , - 'last_updated': , - 'state': 'unknown', - }) -# --- diff --git a/tests/components/tuya/snapshots/test_init.ambr b/tests/components/tuya/snapshots/test_init.ambr index a6d5b121f49..585d1a493ed 100644 --- a/tests/components/tuya/snapshots/test_init.ambr +++ b/tests/components/tuya/snapshots/test_init.ambr @@ -1601,7 +1601,7 @@ 'labels': set({ }), 'manufacturer': 'Tuya', - 'model': 'Tower bladeless fan ', + 'model': 'Tower bladeless fan (unsupported)', 'model_id': 'ibytpo6fpnugft1c', 'name': 'Ventilador Cama', 'name_by_user': None, @@ -2593,7 +2593,7 @@ 'labels': set({ }), 'manufacturer': 'Tuya', - 'model': '', + 'model': ' (unsupported)', 'model_id': 'qhxmvae667uap4zh', 'name': 'DryFix', 'name_by_user': None, @@ -2779,7 +2779,7 @@ 'labels': set({ }), 'manufacturer': 'Tuya', - 'model': 'the Smart Dry Plus™ Connect Dehumidifier ', + 'model': 'the Smart Dry Plus™ Connect Dehumidifier (unsupported)', 'model_id': 'vmxuxszzjwp5smli', 'name': 'Dehumidifier ', 'name_by_user': None,