mirror of
https://github.com/esphome/aioesphomeapi.git
synced 2024-11-27 12:55:32 +01:00
Add slots to all models when using py3.10 or later (#459)
This commit is contained in:
parent
46622cfcef
commit
541ce059c0
@ -427,7 +427,7 @@ class APIClient:
|
||||
# Return CameraState with the merged data
|
||||
image_data = bytes().join(data_parts)
|
||||
del image_stream[msg_key]
|
||||
on_state(CameraState(key=msg.key, data=image_data))
|
||||
on_state(CameraState(key=msg.key, data=image_data)) # type: ignore[call-arg]
|
||||
|
||||
assert self._connection is not None
|
||||
self._connection.send_message_callback_response(
|
||||
@ -847,7 +847,7 @@ class APIClient:
|
||||
|
||||
services.extend(BluetoothGATTServices.from_pb(msg).services)
|
||||
|
||||
return ESPHomeBluetoothGATTServices(address=address, services=services)
|
||||
return ESPHomeBluetoothGATTServices(address=address, services=services) # type: ignore[call-arg]
|
||||
|
||||
async def bluetooth_gatt_read(
|
||||
self,
|
||||
|
@ -1,7 +1,7 @@
|
||||
import enum
|
||||
import sys
|
||||
from dataclasses import asdict, dataclass, field, fields
|
||||
from functools import cache, lru_cache
|
||||
from functools import cache, lru_cache, partial
|
||||
from typing import (
|
||||
TYPE_CHECKING,
|
||||
Any,
|
||||
@ -20,11 +20,12 @@ from uuid import UUID
|
||||
from .util import fix_float_single_double_conversion
|
||||
|
||||
if sys.version_info[:2] < (3, 10):
|
||||
_dataclass_decorator = dataclass()
|
||||
_dataclass_decorator = dataclass
|
||||
_frozen_dataclass_decorator = partial(dataclass, frozen=True)
|
||||
else:
|
||||
_dataclass_decorator = dataclass( # pylint: disable=unexpected-keyword-arg
|
||||
slots=True
|
||||
)
|
||||
_dataclass_decorator = partial(dataclass, slots=True)
|
||||
_frozen_dataclass_decorator = partial(dataclass, frozen=True, slots=True)
|
||||
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .api_pb2 import ( # type: ignore
|
||||
@ -69,7 +70,7 @@ class APIIntEnum(enum.IntEnum):
|
||||
cached_fields = cache(fields)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class APIModelBase:
|
||||
def __post_init__(self) -> None:
|
||||
for field_ in cached_fields(type(self)): # type: ignore[arg-type]
|
||||
@ -78,10 +79,10 @@ class APIModelBase:
|
||||
continue
|
||||
val = getattr(self, field_.name)
|
||||
# use this setattr to prevent FrozenInstanceError
|
||||
super().__setattr__(field_.name, convert(val))
|
||||
object.__setattr__(self, field_.name, convert(val))
|
||||
|
||||
def to_dict(self) -> Dict[str, Any]:
|
||||
return asdict(self)
|
||||
return asdict(self) # type: ignore[no-any-return, call-overload]
|
||||
|
||||
@classmethod
|
||||
def from_dict(
|
||||
@ -124,7 +125,7 @@ class BluetoothProxySubscriptionFlag(enum.IntFlag):
|
||||
RAW_ADVERTISEMENTS = 1 << 0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class DeviceInfo(APIModelBase):
|
||||
uses_password: bool = False
|
||||
name: str = ""
|
||||
@ -165,7 +166,7 @@ class EntityCategory(APIIntEnum):
|
||||
DIAGNOSTIC = 2
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class EntityInfo(APIModelBase):
|
||||
object_id: str = ""
|
||||
key: int = 0
|
||||
@ -178,26 +179,26 @@ class EntityInfo(APIModelBase):
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class EntityState(APIModelBase):
|
||||
key: int = 0
|
||||
|
||||
|
||||
# ==================== BINARY SENSOR ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BinarySensorInfo(EntityInfo):
|
||||
device_class: str = ""
|
||||
is_status_binary_sensor: bool = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BinarySensorState(EntityState):
|
||||
state: bool = False
|
||||
missing_state: bool = False
|
||||
|
||||
|
||||
# ==================== COVER ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class CoverInfo(EntityInfo):
|
||||
assumed_state: bool = False
|
||||
supports_stop: bool = False
|
||||
@ -223,7 +224,7 @@ class CoverOperation(APIIntEnum):
|
||||
IS_CLOSING = 2
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class CoverState(EntityState):
|
||||
legacy_state: Optional[LegacyCoverState] = converter_field(
|
||||
default=LegacyCoverState.OPEN, converter=LegacyCoverState.convert
|
||||
@ -245,7 +246,7 @@ class CoverState(EntityState):
|
||||
|
||||
|
||||
# ==================== FAN ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class FanInfo(EntityInfo):
|
||||
supports_oscillation: bool = False
|
||||
supports_speed: bool = False
|
||||
@ -264,7 +265,7 @@ class FanDirection(APIIntEnum):
|
||||
REVERSE = 1
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class FanState(EntityState):
|
||||
state: bool = False
|
||||
oscillating: bool = False
|
||||
@ -287,7 +288,7 @@ class LightColorCapability(enum.IntFlag):
|
||||
RGB = 1 << 5
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class LightInfo(EntityInfo):
|
||||
supported_color_modes: List[int] = converter_field(
|
||||
default_factory=list, converter=list
|
||||
@ -357,7 +358,7 @@ class LightInfo(EntityInfo):
|
||||
return self.supported_color_modes
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class LightState(EntityState):
|
||||
state: bool = False
|
||||
brightness: float = converter_field(
|
||||
@ -405,7 +406,7 @@ class LastResetType(APIIntEnum):
|
||||
AUTO = 2
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class SensorInfo(EntityInfo):
|
||||
device_class: str = ""
|
||||
unit_of_measurement: str = ""
|
||||
@ -419,43 +420,43 @@ class SensorInfo(EntityInfo):
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class SensorState(EntityState):
|
||||
state: float = 0.0
|
||||
missing_state: bool = False
|
||||
|
||||
|
||||
# ==================== SWITCH ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class SwitchInfo(EntityInfo):
|
||||
assumed_state: bool = False
|
||||
device_class: str = ""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class SwitchState(EntityState):
|
||||
state: bool = False
|
||||
|
||||
|
||||
# ==================== TEXT SENSOR ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class TextSensorInfo(EntityInfo):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class TextSensorState(EntityState):
|
||||
state: str = ""
|
||||
missing_state: bool = False
|
||||
|
||||
|
||||
# ==================== CAMERA ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class CameraInfo(EntityInfo):
|
||||
pass
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class CameraState(EntityState):
|
||||
data: bytes = field(default_factory=bytes)
|
||||
|
||||
@ -511,7 +512,7 @@ class ClimatePreset(APIIntEnum):
|
||||
ACTIVITY = 7
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class ClimateInfo(EntityInfo):
|
||||
supports_current_temperature: bool = False
|
||||
supports_two_point_target_temperature: bool = False
|
||||
@ -558,7 +559,7 @@ class ClimateInfo(EntityInfo):
|
||||
return self.supported_presets
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class ClimateState(EntityState):
|
||||
mode: Optional[ClimateMode] = converter_field(
|
||||
default=ClimateMode.OFF, converter=ClimateMode.convert
|
||||
@ -604,7 +605,7 @@ class NumberMode(APIIntEnum):
|
||||
SLIDER = 2
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class NumberInfo(EntityInfo):
|
||||
min_value: float = converter_field(
|
||||
default=0.0, converter=fix_float_single_double_conversion
|
||||
@ -622,7 +623,7 @@ class NumberInfo(EntityInfo):
|
||||
device_class: str = ""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class NumberState(EntityState):
|
||||
state: float = converter_field(
|
||||
default=0.0, converter=fix_float_single_double_conversion
|
||||
@ -631,32 +632,32 @@ class NumberState(EntityState):
|
||||
|
||||
|
||||
# ==================== SELECT ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class SelectInfo(EntityInfo):
|
||||
options: List[str] = converter_field(default_factory=list, converter=list)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class SelectState(EntityState):
|
||||
state: str = ""
|
||||
missing_state: bool = False
|
||||
|
||||
|
||||
# ==================== SIREN ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class SirenInfo(EntityInfo):
|
||||
tones: List[str] = converter_field(default_factory=list, converter=list)
|
||||
supports_volume: bool = False
|
||||
supports_duration: bool = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class SirenState(EntityState):
|
||||
state: bool = False
|
||||
|
||||
|
||||
# ==================== BUTTON ====================
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class ButtonInfo(EntityInfo):
|
||||
device_class: str = ""
|
||||
|
||||
@ -677,7 +678,7 @@ class LockCommand(APIIntEnum):
|
||||
OPEN = 2
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class LockInfo(EntityInfo):
|
||||
supports_open: bool = False
|
||||
assumed_state: bool = False
|
||||
@ -686,7 +687,7 @@ class LockInfo(EntityInfo):
|
||||
code_format: str = ""
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class LockEntityState(EntityState):
|
||||
state: Optional[LockState] = converter_field(
|
||||
default=LockState.NONE, converter=LockState.convert
|
||||
@ -709,12 +710,12 @@ class MediaPlayerCommand(APIIntEnum):
|
||||
UNMUTE = 4
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class MediaPlayerInfo(EntityInfo):
|
||||
supports_pause: bool = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class MediaPlayerEntityState(EntityState):
|
||||
state: Optional[MediaPlayerState] = converter_field(
|
||||
default=MediaPlayerState.NONE, converter=MediaPlayerState.convert
|
||||
@ -749,14 +750,14 @@ class AlarmControlPanelCommand(APIIntEnum):
|
||||
TRIGGER = 6
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class AlarmControlPanelInfo(EntityInfo):
|
||||
supported_features: int = 0
|
||||
requires_code: bool = False
|
||||
requires_code_to_arm: bool = False
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class AlarmControlPanelEntityState(EntityState):
|
||||
state: Optional[AlarmControlPanelState] = converter_field(
|
||||
default=AlarmControlPanelState.DISARMED,
|
||||
@ -796,7 +797,7 @@ def _convert_homeassistant_service_map(
|
||||
return {v.key: v.value for v in value} # type: ignore
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class HomeassistantServiceCall(APIModelBase):
|
||||
service: str = ""
|
||||
is_event: bool = False
|
||||
@ -822,7 +823,7 @@ class UserServiceArgType(APIIntEnum):
|
||||
STRING_ARRAY = 7
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class UserServiceArg(APIModelBase):
|
||||
name: str = ""
|
||||
type: Optional[UserServiceArgType] = converter_field(
|
||||
@ -842,7 +843,7 @@ class UserServiceArg(APIModelBase):
|
||||
return ret
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class UserService(APIModelBase):
|
||||
name: str = ""
|
||||
key: int = 0
|
||||
@ -955,7 +956,7 @@ def make_ble_raw_advertisement_processor(
|
||||
return _on_ble_raw_advertisement_response
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothDeviceConnection(APIModelBase):
|
||||
address: int = 0
|
||||
connected: bool = False
|
||||
@ -963,28 +964,28 @@ class BluetoothDeviceConnection(APIModelBase):
|
||||
error: int = 0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothDevicePairing(APIModelBase):
|
||||
address: int = 0
|
||||
paired: bool = False
|
||||
error: int = 0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothDeviceUnpairing(APIModelBase):
|
||||
address: int = 0
|
||||
success: bool = False
|
||||
error: int = 0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothDeviceClearCache(APIModelBase):
|
||||
address: int = 0
|
||||
success: bool = False
|
||||
error: int = 0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothGATTRead(APIModelBase):
|
||||
address: int = 0
|
||||
handle: int = 0
|
||||
@ -992,7 +993,7 @@ class BluetoothGATTRead(APIModelBase):
|
||||
data: bytes = field(default_factory=bytes)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothGATTDescriptor(APIModelBase):
|
||||
uuid: str = converter_field(default="", converter=_join_split_uuid)
|
||||
handle: int = 0
|
||||
@ -1008,7 +1009,7 @@ class BluetoothGATTDescriptor(APIModelBase):
|
||||
return ret
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothGATTCharacteristic(APIModelBase):
|
||||
uuid: str = converter_field(default="", converter=_join_split_uuid)
|
||||
handle: int = 0
|
||||
@ -1029,7 +1030,7 @@ class BluetoothGATTCharacteristic(APIModelBase):
|
||||
return ret
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothGATTService(APIModelBase):
|
||||
uuid: str = converter_field(default="", converter=_join_split_uuid)
|
||||
handle: int = 0
|
||||
@ -1048,7 +1049,7 @@ class BluetoothGATTService(APIModelBase):
|
||||
return ret
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothGATTServices(APIModelBase):
|
||||
address: int = 0
|
||||
services: List[BluetoothGATTService] = converter_field(
|
||||
@ -1056,19 +1057,19 @@ class BluetoothGATTServices(APIModelBase):
|
||||
)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class ESPHomeBluetoothGATTServices:
|
||||
address: int = 0
|
||||
services: List[BluetoothGATTService] = field(default_factory=list)
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothConnectionsFree(APIModelBase):
|
||||
free: int = 0
|
||||
limit: int = 0
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class BluetoothGATTError(APIModelBase):
|
||||
address: int = 0
|
||||
handle: int = 0
|
||||
@ -1085,7 +1086,7 @@ class BluetoothDeviceRequestType(APIIntEnum):
|
||||
CLEAR_CACHE = 6
|
||||
|
||||
|
||||
@dataclass(frozen=True)
|
||||
@_frozen_dataclass_decorator
|
||||
class VoiceAssistantCommand(APIModelBase):
|
||||
start: bool = False
|
||||
conversation_id: str = ""
|
||||
|
Loading…
Reference in New Issue
Block a user