Skip to content

Commit fcea5e0

Browse files
authored
Simplify DPType lookup in Tuya (home-assistant#150117)
1 parent 81fd9e1 commit fcea5e0

File tree

4 files changed

+43
-38
lines changed

4 files changed

+43
-38
lines changed

homeassistant/components/tuya/entity.py

Lines changed: 0 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,6 @@
1313
from .const import DOMAIN, LOGGER, TUYA_HA_SIGNAL_UPDATE_ENTITY, DPCode, DPType
1414
from .models import EnumTypeData, IntegerTypeData
1515

16-
_DPTYPE_MAPPING: dict[str, DPType] = {
17-
"bitmap": DPType.BITMAP,
18-
"bool": DPType.BOOLEAN,
19-
"enum": DPType.ENUM,
20-
"json": DPType.JSON,
21-
"raw": DPType.RAW,
22-
"string": DPType.STRING,
23-
"value": DPType.INTEGER,
24-
}
25-
2616

2717
class TuyaEntity(Entity):
2818
"""Tuya base device."""
@@ -125,28 +115,6 @@ def find_dpcode(
125115

126116
return None
127117

128-
def get_dptype(
129-
self, dpcode: DPCode | None, *, prefer_function: bool = False
130-
) -> DPType | None:
131-
"""Find a matching DPCode data type available on for this device."""
132-
if dpcode is None:
133-
return None
134-
135-
order = ["status_range", "function"]
136-
if prefer_function:
137-
order = ["function", "status_range"]
138-
for key in order:
139-
if dpcode in getattr(self.device, key):
140-
current_type = getattr(self.device, key)[dpcode].type
141-
try:
142-
return DPType(current_type)
143-
except ValueError:
144-
# Sometimes, we get ill-formed DPTypes from the cloud,
145-
# this fixes them and maps them to the correct DPType.
146-
return _DPTYPE_MAPPING.get(current_type)
147-
148-
return None
149-
150118
async def async_added_to_hass(self) -> None:
151119
"""Call when entity is added to hass."""
152120
self.async_on_remove(

homeassistant/components/tuya/light.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
from .const import TUYA_DISCOVERY_NEW, DeviceCategory, DPCode, DPType, WorkMode
3030
from .entity import TuyaEntity
3131
from .models import IntegerTypeData
32-
from .util import get_dpcode, remap_value
32+
from .util import get_dpcode, get_dptype, remap_value
3333

3434

3535
@dataclass
@@ -478,9 +478,9 @@ def __init__(
478478
description.brightness_min, dptype=DPType.INTEGER
479479
)
480480

481-
if (
482-
dpcode := get_dpcode(self.device, description.color_data)
483-
) and self.get_dptype(dpcode, prefer_function=True) == DPType.JSON:
481+
if (dpcode := get_dpcode(self.device, description.color_data)) and (
482+
get_dptype(self.device, dpcode, prefer_function=True) == DPType.JSON
483+
):
484484
self._color_data_dpcode = dpcode
485485
color_modes.add(ColorMode.HS)
486486
if dpcode in self.device.function:

homeassistant/components/tuya/sensor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
)
4545
from .entity import TuyaEntity
4646
from .models import ComplexValue, ElectricityValue, EnumTypeData, IntegerTypeData
47+
from .util import get_dptype
4748

4849
_WIND_DIRECTIONS = {
4950
"north": 0.0,
@@ -1689,7 +1690,7 @@ def __init__(
16891690
self._type_data = enum_type
16901691
self._type = DPType.ENUM
16911692
else:
1692-
self._type = self.get_dptype(DPCode(description.key))
1693+
self._type = get_dptype(self.device, DPCode(description.key))
16931694

16941695
# Logic to ensure the set device class and API received Unit Of Measurement
16951696
# match Home Assistants requirements.

homeassistant/components/tuya/util.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,17 @@
66

77
from homeassistant.exceptions import ServiceValidationError
88

9-
from .const import DOMAIN, DPCode
9+
from .const import DOMAIN, DPCode, DPType
10+
11+
_DPTYPE_MAPPING: dict[str, DPType] = {
12+
"bitmap": DPType.BITMAP,
13+
"bool": DPType.BOOLEAN,
14+
"enum": DPType.ENUM,
15+
"json": DPType.JSON,
16+
"raw": DPType.RAW,
17+
"string": DPType.STRING,
18+
"value": DPType.INTEGER,
19+
}
1020

1121

1222
def get_dpcode(
@@ -32,6 +42,32 @@ def get_dpcode(
3242
return None
3343

3444

45+
def get_dptype(
46+
device: CustomerDevice, dpcode: DPCode | None, *, prefer_function: bool = False
47+
) -> DPType | None:
48+
"""Find a matching DPType type information for this device DPCode."""
49+
if dpcode is None:
50+
return None
51+
52+
lookup_tuple = (
53+
(device.function, device.status_range)
54+
if prefer_function
55+
else (device.status_range, device.function)
56+
)
57+
58+
for device_specs in lookup_tuple:
59+
if current_definition := device_specs.get(dpcode):
60+
current_type = current_definition.type
61+
try:
62+
return DPType(current_type)
63+
except ValueError:
64+
# Sometimes, we get ill-formed DPTypes from the cloud,
65+
# this fixes them and maps them to the correct DPType.
66+
return _DPTYPE_MAPPING.get(current_type)
67+
68+
return None
69+
70+
3571
def remap_value(
3672
value: float,
3773
from_min: float = 0,

0 commit comments

Comments
 (0)