Skip to content

Commit eb20292

Browse files
authored
Move tuya models to separate module (home-assistant#148550)
1 parent 12f913e commit eb20292

File tree

11 files changed

+144
-127
lines changed

11 files changed

+144
-127
lines changed

homeassistant/components/tuya/alarm_control_panel.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,8 @@
2020

2121
from . import TuyaConfigEntry
2222
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
23-
from .entity import EnumTypeData, TuyaEntity
23+
from .entity import TuyaEntity
24+
from .models import EnumTypeData
2425

2526

2627
@dataclass(frozen=True)

homeassistant/components/tuya/climate.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
from . import TuyaConfigEntry
2727
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
28-
from .entity import IntegerTypeData, TuyaEntity
28+
from .entity import TuyaEntity
29+
from .models import IntegerTypeData
2930

3031
TUYA_HVAC_TO_HA = {
3132
"auto": HVACMode.HEAT_COOL,

homeassistant/components/tuya/cover.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@
2121

2222
from . import TuyaConfigEntry
2323
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
24-
from .entity import IntegerTypeData, TuyaEntity
24+
from .entity import TuyaEntity
25+
from .models import IntegerTypeData
2526

2627

2728
@dataclass(frozen=True)

homeassistant/components/tuya/entity.py

Lines changed: 2 additions & 118 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,7 @@
22

33
from __future__ import annotations
44

5-
import base64
6-
from dataclasses import dataclass
7-
import json
8-
import struct
9-
from typing import Any, Literal, Self, overload
5+
from typing import Any, Literal, overload
106

117
from tuya_sharing import CustomerDevice, Manager
128

@@ -15,7 +11,7 @@
1511
from homeassistant.helpers.entity import Entity
1612

1713
from .const import DOMAIN, LOGGER, TUYA_HA_SIGNAL_UPDATE_ENTITY, DPCode, DPType
18-
from .util import remap_value
14+
from .models import EnumTypeData, IntegerTypeData
1915

2016
_DPTYPE_MAPPING: dict[str, DPType] = {
2117
"Bitmap": DPType.RAW,
@@ -29,118 +25,6 @@
2925
}
3026

3127

32-
@dataclass
33-
class IntegerTypeData:
34-
"""Integer Type Data."""
35-
36-
dpcode: DPCode
37-
min: int
38-
max: int
39-
scale: float
40-
step: float
41-
unit: str | None = None
42-
type: str | None = None
43-
44-
@property
45-
def max_scaled(self) -> float:
46-
"""Return the max scaled."""
47-
return self.scale_value(self.max)
48-
49-
@property
50-
def min_scaled(self) -> float:
51-
"""Return the min scaled."""
52-
return self.scale_value(self.min)
53-
54-
@property
55-
def step_scaled(self) -> float:
56-
"""Return the step scaled."""
57-
return self.step / (10**self.scale)
58-
59-
def scale_value(self, value: float) -> float:
60-
"""Scale a value."""
61-
return value / (10**self.scale)
62-
63-
def scale_value_back(self, value: float) -> int:
64-
"""Return raw value for scaled."""
65-
return int(value * (10**self.scale))
66-
67-
def remap_value_to(
68-
self,
69-
value: float,
70-
to_min: float = 0,
71-
to_max: float = 255,
72-
reverse: bool = False,
73-
) -> float:
74-
"""Remap a value from this range to a new range."""
75-
return remap_value(value, self.min, self.max, to_min, to_max, reverse)
76-
77-
def remap_value_from(
78-
self,
79-
value: float,
80-
from_min: float = 0,
81-
from_max: float = 255,
82-
reverse: bool = False,
83-
) -> float:
84-
"""Remap a value from its current range to this range."""
85-
return remap_value(value, from_min, from_max, self.min, self.max, reverse)
86-
87-
@classmethod
88-
def from_json(cls, dpcode: DPCode, data: str) -> IntegerTypeData | None:
89-
"""Load JSON string and return a IntegerTypeData object."""
90-
if not (parsed := json.loads(data)):
91-
return None
92-
93-
return cls(
94-
dpcode,
95-
min=int(parsed["min"]),
96-
max=int(parsed["max"]),
97-
scale=float(parsed["scale"]),
98-
step=max(float(parsed["step"]), 1),
99-
unit=parsed.get("unit"),
100-
type=parsed.get("type"),
101-
)
102-
103-
104-
@dataclass
105-
class EnumTypeData:
106-
"""Enum Type Data."""
107-
108-
dpcode: DPCode
109-
range: list[str]
110-
111-
@classmethod
112-
def from_json(cls, dpcode: DPCode, data: str) -> EnumTypeData | None:
113-
"""Load JSON string and return a EnumTypeData object."""
114-
if not (parsed := json.loads(data)):
115-
return None
116-
return cls(dpcode, **parsed)
117-
118-
119-
@dataclass
120-
class ElectricityTypeData:
121-
"""Electricity Type Data."""
122-
123-
electriccurrent: str | None = None
124-
power: str | None = None
125-
voltage: str | None = None
126-
127-
@classmethod
128-
def from_json(cls, data: str) -> Self:
129-
"""Load JSON string and return a ElectricityTypeData object."""
130-
return cls(**json.loads(data.lower()))
131-
132-
@classmethod
133-
def from_raw(cls, data: str) -> Self:
134-
"""Decode base64 string and return a ElectricityTypeData object."""
135-
raw = base64.b64decode(data)
136-
voltage = struct.unpack(">H", raw[0:2])[0] / 10.0
137-
electriccurrent = struct.unpack(">L", b"\x00" + raw[2:5])[0] / 1000.0
138-
power = struct.unpack(">L", b"\x00" + raw[5:8])[0] / 1000.0
139-
return cls(
140-
electriccurrent=str(electriccurrent), power=str(power), voltage=str(voltage)
141-
)
142-
143-
14428
class TuyaEntity(Entity):
14529
"""Tuya base device."""
14630

homeassistant/components/tuya/fan.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@
2222

2323
from . import TuyaConfigEntry
2424
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
25-
from .entity import EnumTypeData, IntegerTypeData, TuyaEntity
25+
from .entity import TuyaEntity
26+
from .models import EnumTypeData, IntegerTypeData
2627

2728
TUYA_SUPPORT_TYPE = {
2829
"cs", # Dehumidifier

homeassistant/components/tuya/humidifier.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@
1919

2020
from . import TuyaConfigEntry
2121
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
22-
from .entity import IntegerTypeData, TuyaEntity
22+
from .entity import TuyaEntity
23+
from .models import IntegerTypeData
2324

2425

2526
@dataclass(frozen=True)

homeassistant/components/tuya/light.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,8 @@
2525

2626
from . import TuyaConfigEntry
2727
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType, WorkMode
28-
from .entity import IntegerTypeData, TuyaEntity
28+
from .entity import TuyaEntity
29+
from .models import IntegerTypeData
2930
from .util import remap_value
3031

3132

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
"""Tuya Home Assistant Base Device Model."""
2+
3+
from __future__ import annotations
4+
5+
import base64
6+
from dataclasses import dataclass
7+
import json
8+
import struct
9+
from typing import Self
10+
11+
from .const import DPCode
12+
from .util import remap_value
13+
14+
15+
@dataclass
16+
class IntegerTypeData:
17+
"""Integer Type Data."""
18+
19+
dpcode: DPCode
20+
min: int
21+
max: int
22+
scale: float
23+
step: float
24+
unit: str | None = None
25+
type: str | None = None
26+
27+
@property
28+
def max_scaled(self) -> float:
29+
"""Return the max scaled."""
30+
return self.scale_value(self.max)
31+
32+
@property
33+
def min_scaled(self) -> float:
34+
"""Return the min scaled."""
35+
return self.scale_value(self.min)
36+
37+
@property
38+
def step_scaled(self) -> float:
39+
"""Return the step scaled."""
40+
return self.step / (10**self.scale)
41+
42+
def scale_value(self, value: float) -> float:
43+
"""Scale a value."""
44+
return value / (10**self.scale)
45+
46+
def scale_value_back(self, value: float) -> int:
47+
"""Return raw value for scaled."""
48+
return int(value * (10**self.scale))
49+
50+
def remap_value_to(
51+
self,
52+
value: float,
53+
to_min: float = 0,
54+
to_max: float = 255,
55+
reverse: bool = False,
56+
) -> float:
57+
"""Remap a value from this range to a new range."""
58+
return remap_value(value, self.min, self.max, to_min, to_max, reverse)
59+
60+
def remap_value_from(
61+
self,
62+
value: float,
63+
from_min: float = 0,
64+
from_max: float = 255,
65+
reverse: bool = False,
66+
) -> float:
67+
"""Remap a value from its current range to this range."""
68+
return remap_value(value, from_min, from_max, self.min, self.max, reverse)
69+
70+
@classmethod
71+
def from_json(cls, dpcode: DPCode, data: str) -> IntegerTypeData | None:
72+
"""Load JSON string and return a IntegerTypeData object."""
73+
if not (parsed := json.loads(data)):
74+
return None
75+
76+
return cls(
77+
dpcode,
78+
min=int(parsed["min"]),
79+
max=int(parsed["max"]),
80+
scale=float(parsed["scale"]),
81+
step=max(float(parsed["step"]), 1),
82+
unit=parsed.get("unit"),
83+
type=parsed.get("type"),
84+
)
85+
86+
87+
@dataclass
88+
class EnumTypeData:
89+
"""Enum Type Data."""
90+
91+
dpcode: DPCode
92+
range: list[str]
93+
94+
@classmethod
95+
def from_json(cls, dpcode: DPCode, data: str) -> EnumTypeData | None:
96+
"""Load JSON string and return a EnumTypeData object."""
97+
if not (parsed := json.loads(data)):
98+
return None
99+
return cls(dpcode, **parsed)
100+
101+
102+
@dataclass
103+
class ElectricityTypeData:
104+
"""Electricity Type Data."""
105+
106+
electriccurrent: str | None = None
107+
power: str | None = None
108+
voltage: str | None = None
109+
110+
@classmethod
111+
def from_json(cls, data: str) -> Self:
112+
"""Load JSON string and return a ElectricityTypeData object."""
113+
return cls(**json.loads(data.lower()))
114+
115+
@classmethod
116+
def from_raw(cls, data: str) -> Self:
117+
"""Decode base64 string and return a ElectricityTypeData object."""
118+
raw = base64.b64decode(data)
119+
voltage = struct.unpack(">H", raw[0:2])[0] / 10.0
120+
electriccurrent = struct.unpack(">L", b"\x00" + raw[2:5])[0] / 1000.0
121+
power = struct.unpack(">L", b"\x00" + raw[5:8])[0] / 1000.0
122+
return cls(
123+
electriccurrent=str(electriccurrent), power=str(power), voltage=str(voltage)
124+
)

homeassistant/components/tuya/number.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,8 @@
1616

1717
from . import TuyaConfigEntry
1818
from .const import DEVICE_CLASS_UNITS, DOMAIN, TUYA_DISCOVERY_NEW, DPCode, DPType
19-
from .entity import IntegerTypeData, TuyaEntity
19+
from .entity import TuyaEntity
20+
from .models import IntegerTypeData
2021

2122
# All descriptions can be found here. Mostly the Integer data types in the
2223
# default instructions set of each category end up being a number.

homeassistant/components/tuya/sensor.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
DPType,
3636
UnitOfMeasurement,
3737
)
38-
from .entity import ElectricityTypeData, EnumTypeData, IntegerTypeData, TuyaEntity
38+
from .entity import TuyaEntity
39+
from .models import ElectricityTypeData, EnumTypeData, IntegerTypeData
3940

4041

4142
@dataclass(frozen=True)

0 commit comments

Comments
 (0)