mirror of
https://github.com/home-assistant/core.git
synced 2025-07-19 03:07:37 +00:00
Fix incorrectly rejected device classes in tuya (#148596)
This commit is contained in:
parent
d8de6e34dd
commit
fae6b375cd
@ -39,6 +39,7 @@ from .const import ( # noqa: F401
|
|||||||
DEFAULT_MAX_VALUE,
|
DEFAULT_MAX_VALUE,
|
||||||
DEFAULT_MIN_VALUE,
|
DEFAULT_MIN_VALUE,
|
||||||
DEFAULT_STEP,
|
DEFAULT_STEP,
|
||||||
|
DEVICE_CLASS_UNITS,
|
||||||
DEVICE_CLASSES_SCHEMA,
|
DEVICE_CLASSES_SCHEMA,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
SERVICE_SET_VALUE,
|
SERVICE_SET_VALUE,
|
||||||
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||||||
from tuya_sharing import CustomerDevice, Manager
|
from tuya_sharing import CustomerDevice, Manager
|
||||||
|
|
||||||
from homeassistant.components.number import (
|
from homeassistant.components.number import (
|
||||||
|
DEVICE_CLASS_UNITS as NUMBER_DEVICE_CLASS_UNITS,
|
||||||
NumberDeviceClass,
|
NumberDeviceClass,
|
||||||
NumberEntity,
|
NumberEntity,
|
||||||
NumberEntityDescription,
|
NumberEntityDescription,
|
||||||
@ -15,7 +16,14 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|||||||
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
||||||
|
|
||||||
from . import TuyaConfigEntry
|
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 .entity import TuyaEntity
|
||||||
from .models import IntegerTypeData
|
from .models import IntegerTypeData
|
||||||
|
|
||||||
@ -371,6 +379,9 @@ class TuyaNumberEntity(TuyaEntity, NumberEntity):
|
|||||||
self.device_class is not None
|
self.device_class is not None
|
||||||
and not self.device_class.startswith(DOMAIN)
|
and not self.device_class.startswith(DOMAIN)
|
||||||
and description.native_unit_of_measurement is None
|
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
|
# We cannot have a device class, if the UOM isn't set or the
|
||||||
# device class cannot be found in the validation mapping.
|
# device class cannot be found in the validation mapping.
|
||||||
@ -378,6 +389,12 @@ class TuyaNumberEntity(TuyaEntity, NumberEntity):
|
|||||||
self.native_unit_of_measurement is None
|
self.native_unit_of_measurement is None
|
||||||
or self.device_class not in DEVICE_CLASS_UNITS
|
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
|
self._attr_device_class = None
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ from tuya_sharing import CustomerDevice, Manager
|
|||||||
from tuya_sharing.device import DeviceStatusRange
|
from tuya_sharing.device import DeviceStatusRange
|
||||||
|
|
||||||
from homeassistant.components.sensor import (
|
from homeassistant.components.sensor import (
|
||||||
|
DEVICE_CLASS_UNITS as SENSOR_DEVICE_CLASS_UNITS,
|
||||||
SensorDeviceClass,
|
SensorDeviceClass,
|
||||||
SensorEntity,
|
SensorEntity,
|
||||||
SensorEntityDescription,
|
SensorEntityDescription,
|
||||||
@ -32,6 +33,7 @@ from . import TuyaConfigEntry
|
|||||||
from .const import (
|
from .const import (
|
||||||
DEVICE_CLASS_UNITS,
|
DEVICE_CLASS_UNITS,
|
||||||
DOMAIN,
|
DOMAIN,
|
||||||
|
LOGGER,
|
||||||
TUYA_DISCOVERY_NEW,
|
TUYA_DISCOVERY_NEW,
|
||||||
DPCode,
|
DPCode,
|
||||||
DPType,
|
DPType,
|
||||||
@ -1438,6 +1440,9 @@ class TuyaSensorEntity(TuyaEntity, SensorEntity):
|
|||||||
self.device_class is not None
|
self.device_class is not None
|
||||||
and not self.device_class.startswith(DOMAIN)
|
and not self.device_class.startswith(DOMAIN)
|
||||||
and description.native_unit_of_measurement is None
|
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
|
# We cannot have a device class, if the UOM isn't set or the
|
||||||
# device class cannot be found in the validation mapping.
|
# device class cannot be found in the validation mapping.
|
||||||
@ -1445,6 +1450,12 @@ class TuyaSensorEntity(TuyaEntity, SensorEntity):
|
|||||||
self.native_unit_of_measurement is None
|
self.native_unit_of_measurement is None
|
||||||
or self.device_class not in DEVICE_CLASS_UNITS
|
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
|
self._attr_device_class = None
|
||||||
return
|
return
|
||||||
|
|
||||||
|
@ -181,8 +181,11 @@
|
|||||||
}),
|
}),
|
||||||
'name': None,
|
'name': None,
|
||||||
'options': dict({
|
'options': dict({
|
||||||
|
'sensor': dict({
|
||||||
|
'suggested_display_precision': 2,
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
'original_device_class': None,
|
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
|
||||||
'original_icon': None,
|
'original_icon': None,
|
||||||
'original_name': 'Filter duration',
|
'original_name': 'Filter duration',
|
||||||
'platform': 'tuya',
|
'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]
|
# name: test_platform_setup_and_discovery[cwysj_pixi_smart_drinking_fountain][sensor.pixi_smart_drinking_fountain_filter_duration-state]
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'duration',
|
||||||
'friendly_name': 'PIXI Smart Drinking Fountain Filter duration',
|
'friendly_name': 'PIXI Smart Drinking Fountain Filter duration',
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': 'min',
|
'unit_of_measurement': 'min',
|
||||||
@ -233,8 +237,11 @@
|
|||||||
}),
|
}),
|
||||||
'name': None,
|
'name': None,
|
||||||
'options': dict({
|
'options': dict({
|
||||||
|
'sensor': dict({
|
||||||
|
'suggested_display_precision': 2,
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
'original_device_class': None,
|
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
|
||||||
'original_icon': None,
|
'original_icon': None,
|
||||||
'original_name': 'UV runtime',
|
'original_name': 'UV runtime',
|
||||||
'platform': 'tuya',
|
'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]
|
# name: test_platform_setup_and_discovery[cwysj_pixi_smart_drinking_fountain][sensor.pixi_smart_drinking_fountain_uv_runtime-state]
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'duration',
|
||||||
'friendly_name': 'PIXI Smart Drinking Fountain UV runtime',
|
'friendly_name': 'PIXI Smart Drinking Fountain UV runtime',
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': 's',
|
'unit_of_measurement': 's',
|
||||||
@ -333,8 +341,11 @@
|
|||||||
}),
|
}),
|
||||||
'name': None,
|
'name': None,
|
||||||
'options': dict({
|
'options': dict({
|
||||||
|
'sensor': dict({
|
||||||
|
'suggested_display_precision': 2,
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
'original_device_class': None,
|
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
|
||||||
'original_icon': None,
|
'original_icon': None,
|
||||||
'original_name': 'Water pump duration',
|
'original_name': 'Water pump duration',
|
||||||
'platform': 'tuya',
|
'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]
|
# name: test_platform_setup_and_discovery[cwysj_pixi_smart_drinking_fountain][sensor.pixi_smart_drinking_fountain_water_pump_duration-state]
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'duration',
|
||||||
'friendly_name': 'PIXI Smart Drinking Fountain Water pump duration',
|
'friendly_name': 'PIXI Smart Drinking Fountain Water pump duration',
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': 'min',
|
'unit_of_measurement': 'min',
|
||||||
@ -385,8 +397,11 @@
|
|||||||
}),
|
}),
|
||||||
'name': None,
|
'name': None,
|
||||||
'options': dict({
|
'options': dict({
|
||||||
|
'sensor': dict({
|
||||||
|
'suggested_display_precision': 2,
|
||||||
|
}),
|
||||||
}),
|
}),
|
||||||
'original_device_class': None,
|
'original_device_class': <SensorDeviceClass.DURATION: 'duration'>,
|
||||||
'original_icon': None,
|
'original_icon': None,
|
||||||
'original_name': 'Water usage duration',
|
'original_name': 'Water usage duration',
|
||||||
'platform': 'tuya',
|
'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]
|
# name: test_platform_setup_and_discovery[cwysj_pixi_smart_drinking_fountain][sensor.pixi_smart_drinking_fountain_water_usage_duration-state]
|
||||||
StateSnapshot({
|
StateSnapshot({
|
||||||
'attributes': ReadOnlyDict({
|
'attributes': ReadOnlyDict({
|
||||||
|
'device_class': 'duration',
|
||||||
'friendly_name': 'PIXI Smart Drinking Fountain Water usage duration',
|
'friendly_name': 'PIXI Smart Drinking Fountain Water usage duration',
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': 'min',
|
'unit_of_measurement': 'min',
|
||||||
@ -509,7 +525,7 @@
|
|||||||
'supported_features': 0,
|
'supported_features': 0,
|
||||||
'translation_key': 'power',
|
'translation_key': 'power',
|
||||||
'unique_id': 'tuya.eb0c772dabbb19d653ssi5cur_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]
|
# name: test_platform_setup_and_discovery[cz_dual_channel_metering][sensor.hvac_meter_power-state]
|
||||||
@ -518,7 +534,7 @@
|
|||||||
'device_class': 'power',
|
'device_class': 'power',
|
||||||
'friendly_name': 'HVAC Meter Power',
|
'friendly_name': 'HVAC Meter Power',
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
'unit_of_measurement': 'W',
|
||||||
}),
|
}),
|
||||||
'context': <ANY>,
|
'context': <ANY>,
|
||||||
'entity_id': 'sensor.hvac_meter_power',
|
'entity_id': 'sensor.hvac_meter_power',
|
||||||
@ -683,7 +699,7 @@
|
|||||||
'supported_features': 0,
|
'supported_features': 0,
|
||||||
'translation_key': 'power',
|
'translation_key': 'power',
|
||||||
'unique_id': 'tuya.mocked_device_idcur_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]
|
# 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',
|
'device_class': 'power',
|
||||||
'friendly_name': '一路带计量磁保持通断器 Power',
|
'friendly_name': '一路带计量磁保持通断器 Power',
|
||||||
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
'state_class': <SensorStateClass.MEASUREMENT: 'measurement'>,
|
||||||
'unit_of_measurement': <UnitOfPower.WATT: 'W'>,
|
'unit_of_measurement': 'W',
|
||||||
}),
|
}),
|
||||||
'context': <ANY>,
|
'context': <ANY>,
|
||||||
'entity_id': 'sensor.yi_lu_dai_ji_liang_ci_bao_chi_tong_duan_qi_power',
|
'entity_id': 'sensor.yi_lu_dai_ji_liang_ci_bao_chi_tong_duan_qi_power',
|
||||||
|
Loading…
x
Reference in New Issue
Block a user