mirror of
https://github.com/home-assistant/core.git
synced 2025-07-28 23:57:06 +00:00
Move tuya models to separate module (#148550)
This commit is contained in:
parent
12f913e737
commit
eb20292683
@ -20,7 +20,8 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
|
|
||||||
from . import TuyaConfigEntry
|
from . import TuyaConfigEntry
|
||||||
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
||||||
from .entity import EnumTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import EnumTypeData
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
@ -25,7 +25,8 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
|
|
||||||
from . import TuyaConfigEntry
|
from . import TuyaConfigEntry
|
||||||
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
||||||
from .entity import IntegerTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import IntegerTypeData
|
||||||
|
|
||||||
TUYA_HVAC_TO_HA = {
|
TUYA_HVAC_TO_HA = {
|
||||||
"auto": HVACMode.HEAT_COOL,
|
"auto": HVACMode.HEAT_COOL,
|
||||||
|
@ -21,7 +21,8 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
|
|
||||||
from . import TuyaConfigEntry
|
from . import TuyaConfigEntry
|
||||||
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
||||||
from .entity import IntegerTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import IntegerTypeData
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
@ -2,11 +2,7 @@
|
|||||||
|
|
||||||
from __future__ import annotations
|
from __future__ import annotations
|
||||||
|
|
||||||
import base64
|
from typing import Any, Literal, overload
|
||||||
from dataclasses import dataclass
|
|
||||||
import json
|
|
||||||
import struct
|
|
||||||
from typing import Any, Literal, Self, overload
|
|
||||||
|
|
||||||
from tuya_sharing import CustomerDevice, Manager
|
from tuya_sharing import CustomerDevice, Manager
|
||||||
|
|
||||||
@ -15,7 +11,7 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|||||||
from homeassistant.helpers.entity import Entity
|
from homeassistant.helpers.entity import Entity
|
||||||
|
|
||||||
from .const import DOMAIN, LOGGER, TUYA_HA_SIGNAL_UPDATE_ENTITY, DPCode, DPType
|
from .const import DOMAIN, LOGGER, TUYA_HA_SIGNAL_UPDATE_ENTITY, DPCode, DPType
|
||||||
from .util import remap_value
|
from .models import EnumTypeData, IntegerTypeData
|
||||||
|
|
||||||
_DPTYPE_MAPPING: dict[str, DPType] = {
|
_DPTYPE_MAPPING: dict[str, DPType] = {
|
||||||
"Bitmap": DPType.RAW,
|
"Bitmap": DPType.RAW,
|
||||||
@ -29,118 +25,6 @@ _DPTYPE_MAPPING: dict[str, DPType] = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class IntegerTypeData:
|
|
||||||
"""Integer Type Data."""
|
|
||||||
|
|
||||||
dpcode: DPCode
|
|
||||||
min: int
|
|
||||||
max: int
|
|
||||||
scale: float
|
|
||||||
step: float
|
|
||||||
unit: str | None = None
|
|
||||||
type: str | None = None
|
|
||||||
|
|
||||||
@property
|
|
||||||
def max_scaled(self) -> float:
|
|
||||||
"""Return the max scaled."""
|
|
||||||
return self.scale_value(self.max)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def min_scaled(self) -> float:
|
|
||||||
"""Return the min scaled."""
|
|
||||||
return self.scale_value(self.min)
|
|
||||||
|
|
||||||
@property
|
|
||||||
def step_scaled(self) -> float:
|
|
||||||
"""Return the step scaled."""
|
|
||||||
return self.step / (10**self.scale)
|
|
||||||
|
|
||||||
def scale_value(self, value: float) -> float:
|
|
||||||
"""Scale a value."""
|
|
||||||
return value / (10**self.scale)
|
|
||||||
|
|
||||||
def scale_value_back(self, value: float) -> int:
|
|
||||||
"""Return raw value for scaled."""
|
|
||||||
return int(value * (10**self.scale))
|
|
||||||
|
|
||||||
def remap_value_to(
|
|
||||||
self,
|
|
||||||
value: float,
|
|
||||||
to_min: float = 0,
|
|
||||||
to_max: float = 255,
|
|
||||||
reverse: bool = False,
|
|
||||||
) -> float:
|
|
||||||
"""Remap a value from this range to a new range."""
|
|
||||||
return remap_value(value, self.min, self.max, to_min, to_max, reverse)
|
|
||||||
|
|
||||||
def remap_value_from(
|
|
||||||
self,
|
|
||||||
value: float,
|
|
||||||
from_min: float = 0,
|
|
||||||
from_max: float = 255,
|
|
||||||
reverse: bool = False,
|
|
||||||
) -> float:
|
|
||||||
"""Remap a value from its current range to this range."""
|
|
||||||
return remap_value(value, from_min, from_max, self.min, self.max, reverse)
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_json(cls, dpcode: DPCode, data: str) -> IntegerTypeData | None:
|
|
||||||
"""Load JSON string and return a IntegerTypeData object."""
|
|
||||||
if not (parsed := json.loads(data)):
|
|
||||||
return None
|
|
||||||
|
|
||||||
return cls(
|
|
||||||
dpcode,
|
|
||||||
min=int(parsed["min"]),
|
|
||||||
max=int(parsed["max"]),
|
|
||||||
scale=float(parsed["scale"]),
|
|
||||||
step=max(float(parsed["step"]), 1),
|
|
||||||
unit=parsed.get("unit"),
|
|
||||||
type=parsed.get("type"),
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class EnumTypeData:
|
|
||||||
"""Enum Type Data."""
|
|
||||||
|
|
||||||
dpcode: DPCode
|
|
||||||
range: list[str]
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_json(cls, dpcode: DPCode, data: str) -> EnumTypeData | None:
|
|
||||||
"""Load JSON string and return a EnumTypeData object."""
|
|
||||||
if not (parsed := json.loads(data)):
|
|
||||||
return None
|
|
||||||
return cls(dpcode, **parsed)
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class ElectricityTypeData:
|
|
||||||
"""Electricity Type Data."""
|
|
||||||
|
|
||||||
electriccurrent: str | None = None
|
|
||||||
power: str | None = None
|
|
||||||
voltage: str | None = None
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_json(cls, data: str) -> Self:
|
|
||||||
"""Load JSON string and return a ElectricityTypeData object."""
|
|
||||||
return cls(**json.loads(data.lower()))
|
|
||||||
|
|
||||||
@classmethod
|
|
||||||
def from_raw(cls, data: str) -> Self:
|
|
||||||
"""Decode base64 string and return a ElectricityTypeData object."""
|
|
||||||
raw = base64.b64decode(data)
|
|
||||||
voltage = struct.unpack(">H", raw[0:2])[0] / 10.0
|
|
||||||
electriccurrent = struct.unpack(">L", b"\x00" + raw[2:5])[0] / 1000.0
|
|
||||||
power = struct.unpack(">L", b"\x00" + raw[5:8])[0] / 1000.0
|
|
||||||
return cls(
|
|
||||||
electriccurrent=str(electriccurrent), power=str(power), voltage=str(voltage)
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
class TuyaEntity(Entity):
|
class TuyaEntity(Entity):
|
||||||
"""Tuya base device."""
|
"""Tuya base device."""
|
||||||
|
|
||||||
|
@ -22,7 +22,8 @@ from homeassistant.util.percentage import (
|
|||||||
|
|
||||||
from . import TuyaConfigEntry
|
from . import TuyaConfigEntry
|
||||||
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
||||||
from .entity import EnumTypeData, IntegerTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import EnumTypeData, IntegerTypeData
|
||||||
|
|
||||||
TUYA_SUPPORT_TYPE = {
|
TUYA_SUPPORT_TYPE = {
|
||||||
"cs", # Dehumidifier
|
"cs", # Dehumidifier
|
||||||
|
@ -19,7 +19,8 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
|
|
||||||
from . import TuyaConfigEntry
|
from . import TuyaConfigEntry
|
||||||
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
||||||
from .entity import IntegerTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import IntegerTypeData
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
@ -25,7 +25,8 @@ from homeassistant.util import color as color_util
|
|||||||
|
|
||||||
from . import TuyaConfigEntry
|
from . import TuyaConfigEntry
|
||||||
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType, WorkMode
|
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType, WorkMode
|
||||||
from .entity import IntegerTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import IntegerTypeData
|
||||||
from .util import remap_value
|
from .util import remap_value
|
||||||
|
|
||||||
|
|
||||||
|
124
homeassistant/components/tuya/models.py
Normal file
124
homeassistant/components/tuya/models.py
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
"""Tuya Home Assistant Base Device Model."""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import base64
|
||||||
|
from dataclasses import dataclass
|
||||||
|
import json
|
||||||
|
import struct
|
||||||
|
from typing import Self
|
||||||
|
|
||||||
|
from .const import DPCode
|
||||||
|
from .util import remap_value
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class IntegerTypeData:
|
||||||
|
"""Integer Type Data."""
|
||||||
|
|
||||||
|
dpcode: DPCode
|
||||||
|
min: int
|
||||||
|
max: int
|
||||||
|
scale: float
|
||||||
|
step: float
|
||||||
|
unit: str | None = None
|
||||||
|
type: str | None = None
|
||||||
|
|
||||||
|
@property
|
||||||
|
def max_scaled(self) -> float:
|
||||||
|
"""Return the max scaled."""
|
||||||
|
return self.scale_value(self.max)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def min_scaled(self) -> float:
|
||||||
|
"""Return the min scaled."""
|
||||||
|
return self.scale_value(self.min)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def step_scaled(self) -> float:
|
||||||
|
"""Return the step scaled."""
|
||||||
|
return self.step / (10**self.scale)
|
||||||
|
|
||||||
|
def scale_value(self, value: float) -> float:
|
||||||
|
"""Scale a value."""
|
||||||
|
return value / (10**self.scale)
|
||||||
|
|
||||||
|
def scale_value_back(self, value: float) -> int:
|
||||||
|
"""Return raw value for scaled."""
|
||||||
|
return int(value * (10**self.scale))
|
||||||
|
|
||||||
|
def remap_value_to(
|
||||||
|
self,
|
||||||
|
value: float,
|
||||||
|
to_min: float = 0,
|
||||||
|
to_max: float = 255,
|
||||||
|
reverse: bool = False,
|
||||||
|
) -> float:
|
||||||
|
"""Remap a value from this range to a new range."""
|
||||||
|
return remap_value(value, self.min, self.max, to_min, to_max, reverse)
|
||||||
|
|
||||||
|
def remap_value_from(
|
||||||
|
self,
|
||||||
|
value: float,
|
||||||
|
from_min: float = 0,
|
||||||
|
from_max: float = 255,
|
||||||
|
reverse: bool = False,
|
||||||
|
) -> float:
|
||||||
|
"""Remap a value from its current range to this range."""
|
||||||
|
return remap_value(value, from_min, from_max, self.min, self.max, reverse)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, dpcode: DPCode, data: str) -> IntegerTypeData | None:
|
||||||
|
"""Load JSON string and return a IntegerTypeData object."""
|
||||||
|
if not (parsed := json.loads(data)):
|
||||||
|
return None
|
||||||
|
|
||||||
|
return cls(
|
||||||
|
dpcode,
|
||||||
|
min=int(parsed["min"]),
|
||||||
|
max=int(parsed["max"]),
|
||||||
|
scale=float(parsed["scale"]),
|
||||||
|
step=max(float(parsed["step"]), 1),
|
||||||
|
unit=parsed.get("unit"),
|
||||||
|
type=parsed.get("type"),
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class EnumTypeData:
|
||||||
|
"""Enum Type Data."""
|
||||||
|
|
||||||
|
dpcode: DPCode
|
||||||
|
range: list[str]
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, dpcode: DPCode, data: str) -> EnumTypeData | None:
|
||||||
|
"""Load JSON string and return a EnumTypeData object."""
|
||||||
|
if not (parsed := json.loads(data)):
|
||||||
|
return None
|
||||||
|
return cls(dpcode, **parsed)
|
||||||
|
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class ElectricityTypeData:
|
||||||
|
"""Electricity Type Data."""
|
||||||
|
|
||||||
|
electriccurrent: str | None = None
|
||||||
|
power: str | None = None
|
||||||
|
voltage: str | None = None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_json(cls, data: str) -> Self:
|
||||||
|
"""Load JSON string and return a ElectricityTypeData object."""
|
||||||
|
return cls(**json.loads(data.lower()))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def from_raw(cls, data: str) -> Self:
|
||||||
|
"""Decode base64 string and return a ElectricityTypeData object."""
|
||||||
|
raw = base64.b64decode(data)
|
||||||
|
voltage = struct.unpack(">H", raw[0:2])[0] / 10.0
|
||||||
|
electriccurrent = struct.unpack(">L", b"\x00" + raw[2:5])[0] / 1000.0
|
||||||
|
power = struct.unpack(">L", b"\x00" + raw[5:8])[0] / 1000.0
|
||||||
|
return cls(
|
||||||
|
electriccurrent=str(electriccurrent), power=str(power), voltage=str(voltage)
|
||||||
|
)
|
@ -16,7 +16,8 @@ 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, TUYA_DISCOVERY_NEW, DPCode, DPType
|
||||||
from .entity import IntegerTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import IntegerTypeData
|
||||||
|
|
||||||
# All descriptions can be found here. Mostly the Integer data types in the
|
# All descriptions can be found here. Mostly the Integer data types in the
|
||||||
# default instructions set of each category end up being a number.
|
# default instructions set of each category end up being a number.
|
||||||
|
@ -35,7 +35,8 @@ from .const import (
|
|||||||
DPType,
|
DPType,
|
||||||
UnitOfMeasurement,
|
UnitOfMeasurement,
|
||||||
)
|
)
|
||||||
from .entity import ElectricityTypeData, EnumTypeData, IntegerTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import ElectricityTypeData, EnumTypeData, IntegerTypeData
|
||||||
|
|
||||||
|
|
||||||
@dataclass(frozen=True)
|
@dataclass(frozen=True)
|
||||||
|
@ -17,7 +17,8 @@ from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
|
|||||||
|
|
||||||
from . import TuyaConfigEntry
|
from . import TuyaConfigEntry
|
||||||
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
from .const import TUYA_DISCOVERY_NEW, DPCode, DPType
|
||||||
from .entity import EnumTypeData, IntegerTypeData, TuyaEntity
|
from .entity import TuyaEntity
|
||||||
|
from .models import EnumTypeData, IntegerTypeData
|
||||||
|
|
||||||
TUYA_MODE_RETURN_HOME = "chargego"
|
TUYA_MODE_RETURN_HOME = "chargego"
|
||||||
TUYA_STATUS_TO_HA = {
|
TUYA_STATUS_TO_HA = {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user