Fix incorrectly rejected device classes in tuya (#148596)

This commit is contained in:
epenet 2025-07-16 09:39:22 +02:00 committed by GitHub
parent d8de6e34dd
commit fae6b375cd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 54 additions and 9 deletions

View File

@ -39,6 +39,7 @@ from .const import ( # noqa: F401
DEFAULT_MAX_VALUE,
DEFAULT_MIN_VALUE,
DEFAULT_STEP,
DEVICE_CLASS_UNITS,
DEVICE_CLASSES_SCHEMA,
DOMAIN,
SERVICE_SET_VALUE,

View File

@ -5,6 +5,7 @@ from __future__ import annotations
from tuya_sharing import CustomerDevice, Manager
from homeassistant.components.number import (
DEVICE_CLASS_UNITS as NUMBER_DEVICE_CLASS_UNITS,
NumberDeviceClass,
NumberEntity,
NumberEntityDescription,
@ -15,7 +16,14 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
from . import TuyaConfigEntry
from .const import DEVICE_CLASS_UNITS, DOMAIN, TUYA_DISCOVERY_NEW, DPCode, DPType
from .const import (
DEVICE_CLASS_UNITS,
DOMAIN,
LOGGER,
TUYA_DISCOVERY_NEW,
DPCode,
DPType,
)
from .entity import TuyaEntity
from .models import IntegerTypeData
@ -371,6 +379,9 @@ class TuyaNumberEntity(TuyaEntity, NumberEntity):
self.device_class is not None
and not self.device_class.startswith(DOMAIN)
and description.native_unit_of_measurement is None
# we do not need to check mappings if the API UOM is allowed
and self.native_unit_of_measurement
not in NUMBER_DEVICE_CLASS_UNITS[self.device_class]
):
# We cannot have a device class, if the UOM isn't set or the
# device class cannot be found in the validation mapping.
@ -378,6 +389,12 @@ class TuyaNumberEntity(TuyaEntity, NumberEntity):
self.native_unit_of_measurement is None
or self.device_class not in DEVICE_CLASS_UNITS
):
LOGGER.debug(
"Device class %s ignored for incompatible unit %s in number entity %s",
self.device_class,
self.native_unit_of_measurement,
self.unique_id,
)
self._attr_device_class = None
return

View File

@ -8,6 +8,7 @@ from tuya_sharing import CustomerDevice, Manager
from tuya_sharing.device import DeviceStatusRange
from homeassistant.components.sensor import (
DEVICE_CLASS_UNITS as SENSOR_DEVICE_CLASS_UNITS,
SensorDeviceClass,
SensorEntity,
SensorEntityDescription,
@ -32,6 +33,7 @@ from . import TuyaConfigEntry
from .const import (
DEVICE_CLASS_UNITS,
DOMAIN,
LOGGER,
TUYA_DISCOVERY_NEW,
DPCode,
DPType,
@ -1438,6 +1440,9 @@ class TuyaSensorEntity(TuyaEntity, SensorEntity):
self.device_class is not None
and not self.device_class.startswith(DOMAIN)
and description.native_unit_of_measurement is None
# we do not need to check mappings if the API UOM is allowed
and self.native_unit_of_measurement
not in SENSOR_DEVICE_CLASS_UNITS[self.device_class]
):
# We cannot have a device class, if the UOM isn't set or the
# device class cannot be found in the validation mapping.
@ -1445,6 +1450,12 @@ class TuyaSensorEntity(TuyaEntity, SensorEntity):
self.native_unit_of_measurement is None
or self.device_class not in DEVICE_CLASS_UNITS
):
LOGGER.debug(
"Device class %s ignored for incompatible unit %s in sensor entity %s",
self.device_class,
self.native_unit_of_measurement,
self.unique_id,
)
self._attr_device_class = None
return

View File

@ -181,8 +181,11 @@
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'original_device_class': None,
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_icon': None,
'original_name': 'Filter duration',
'platform': 'tuya',
@ -197,6 +200,7 @@
# name: test_platform_setup_and_discovery[cwysj_pixi_smart_drinking_fountain][sensor.pixi_smart_drinking_fountain_filter_duration-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'friendly_name': 'PIXI Smart Drinking Fountain Filter duration',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': 'min',
@ -233,8 +237,11 @@
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'original_device_class': None,
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_icon': None,
'original_name': 'UV runtime',
'platform': 'tuya',
@ -249,6 +256,7 @@
# name: test_platform_setup_and_discovery[cwysj_pixi_smart_drinking_fountain][sensor.pixi_smart_drinking_fountain_uv_runtime-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'friendly_name': 'PIXI Smart Drinking Fountain UV runtime',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': 's',
@ -333,8 +341,11 @@
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'original_device_class': None,
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_icon': None,
'original_name': 'Water pump duration',
'platform': 'tuya',
@ -349,6 +360,7 @@
# name: test_platform_setup_and_discovery[cwysj_pixi_smart_drinking_fountain][sensor.pixi_smart_drinking_fountain_water_pump_duration-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'friendly_name': 'PIXI Smart Drinking Fountain Water pump duration',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': 'min',
@ -385,8 +397,11 @@
}),
'name': None,
'options': dict({
'sensor': dict({
'suggested_display_precision': 2,
}),
'original_device_class': None,
}),
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
'original_icon': None,
'original_name': 'Water usage duration',
'platform': 'tuya',
@ -401,6 +416,7 @@
# name: test_platform_setup_and_discovery[cwysj_pixi_smart_drinking_fountain][sensor.pixi_smart_drinking_fountain_water_usage_duration-state]
StateSnapshot({
'attributes': ReadOnlyDict({
'device_class': 'duration',
'friendly_name': 'PIXI Smart Drinking Fountain Water usage duration',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': 'min',
@ -509,7 +525,7 @@
'supported_features': 0,
'translation_key': 'power',
'unique_id': 'tuya.eb0c772dabbb19d653ssi5cur_power',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
'unit_of_measurement': 'W',
})
# ---
# name: test_platform_setup_and_discovery[cz_dual_channel_metering][sensor.hvac_meter_power-state]
@ -518,7 +534,7 @@
'device_class': 'power',
'friendly_name': 'HVAC Meter Power',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
'unit_of_measurement': 'W',
}),
'context': <ANY>,
'entity_id': 'sensor.hvac_meter_power',
@ -683,7 +699,7 @@
'supported_features': 0,
'translation_key': 'power',
'unique_id': 'tuya.mocked_device_idcur_power',
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
'unit_of_measurement': 'W',
})
# ---
# name: test_platform_setup_and_discovery[dlq_earu_electric_eawcpt][sensor.yi_lu_dai_ji_liang_ci_bao_chi_tong_duan_qi_power-state]
@ -692,7 +708,7 @@
'device_class': 'power',
'friendly_name': '一路带计量磁保持通断器 Power',
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
'unit_of_measurement': 'W',
}),
'context': <ANY>,
'entity_id': 'sensor.yi_lu_dai_ji_liang_ci_bao_chi_tong_duan_qi_power',