python
This commit is contained in:
140
custom_components/yandex_smart_home/property.py
Normal file
140
custom_components/yandex_smart_home/property.py
Normal file
@@ -0,0 +1,140 @@
|
||||
"""Implement the Yandex Smart Home base device property."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from abc import abstractmethod
|
||||
from typing import TYPE_CHECKING, Any, Protocol, Self, runtime_checkable
|
||||
|
||||
from homeassistant.const import ATTR_DEVICE_CLASS
|
||||
from homeassistant.core import HomeAssistant, State
|
||||
|
||||
from .helpers import ListRegistry
|
||||
from .schema import (
|
||||
PropertyDescription,
|
||||
PropertyInstance,
|
||||
PropertyInstanceState,
|
||||
PropertyInstanceStateValue,
|
||||
PropertyParameters,
|
||||
PropertyType,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from .entry_data import ConfigEntryData
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class Property(Protocol):
|
||||
"""Base class for a device property."""
|
||||
|
||||
device_id: str
|
||||
type: PropertyType
|
||||
instance: PropertyInstance
|
||||
|
||||
_hass: HomeAssistant
|
||||
_entry_data: ConfigEntryData
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def supported(self) -> bool:
|
||||
"""Test if the property is supported."""
|
||||
...
|
||||
|
||||
@property
|
||||
def retrievable(self) -> bool:
|
||||
"""Test if the property can return the current value."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def reportable(self) -> bool:
|
||||
"""Test if the property can report value changes."""
|
||||
return self._entry_data.is_reporting_states
|
||||
|
||||
@property
|
||||
def heartbeat_report(self) -> bool:
|
||||
"""Test if property value should be reported on startup and periodically."""
|
||||
return True
|
||||
|
||||
@property
|
||||
def time_sensitive(self) -> bool:
|
||||
"""Test if value changes should be reported immediately."""
|
||||
return False
|
||||
|
||||
@property
|
||||
@abstractmethod
|
||||
def parameters(self) -> PropertyParameters:
|
||||
"""Return parameters for a devices list request."""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def get_description(self) -> PropertyDescription:
|
||||
"""Return a description for a device list request."""
|
||||
...
|
||||
|
||||
@abstractmethod
|
||||
def get_value(self) -> Any:
|
||||
"""Return the current property value."""
|
||||
...
|
||||
|
||||
def get_instance_state(self) -> PropertyInstanceState | None:
|
||||
"""Return a state for a state query request."""
|
||||
if (value := self.get_value()) is not None:
|
||||
return PropertyInstanceState(
|
||||
type=self.type, state=PropertyInstanceStateValue(instance=self.instance, value=value)
|
||||
)
|
||||
|
||||
return None
|
||||
|
||||
@abstractmethod
|
||||
def check_value_change(self, other: Self | None) -> bool:
|
||||
"""Test if the property value differs from other property."""
|
||||
...
|
||||
|
||||
def __str__(self) -> str:
|
||||
"""Return string representation."""
|
||||
return f"instance {self.instance} of {self.type.short} property of {self.device_id}"
|
||||
|
||||
def __repr__(self) -> str:
|
||||
"""Return the representation."""
|
||||
return (
|
||||
f"<{self.__class__.__name__}"
|
||||
f" device_id={self.device_id }"
|
||||
f" type={self.type}"
|
||||
f" instance={self.instance}"
|
||||
f">"
|
||||
)
|
||||
|
||||
def __eq__(self, other: Any) -> bool:
|
||||
"""Compare properties."""
|
||||
return bool(
|
||||
isinstance(other, Property)
|
||||
and self.type == other.type
|
||||
and self.instance == other.instance
|
||||
and self.device_id == other.device_id
|
||||
)
|
||||
|
||||
|
||||
@runtime_checkable
|
||||
class StateProperty(Property, Protocol):
|
||||
"""Base class for a device property based on the state."""
|
||||
|
||||
state: State
|
||||
device_id: str
|
||||
|
||||
_hass: HomeAssistant
|
||||
_entry_data: ConfigEntryData
|
||||
|
||||
def __init__(self, hass: HomeAssistant, entry_data: ConfigEntryData, device_id: str, state: State):
|
||||
"""Initialize a property for the state."""
|
||||
self._hass = hass
|
||||
self._entry_data = entry_data
|
||||
|
||||
self.state = state
|
||||
self.device_id = device_id
|
||||
|
||||
@property
|
||||
def _state_device_class(self) -> str | None:
|
||||
"""Return state device class."""
|
||||
return self.state.attributes.get(ATTR_DEVICE_CLASS)
|
||||
|
||||
|
||||
STATE_PROPERTIES_REGISTRY = ListRegistry[type[StateProperty]]()
|
||||
Reference in New Issue
Block a user