This commit is contained in:
Victor Alexandrovich Tsyrenschikov
2026-03-30 20:25:42 +05:00
parent 139f9f1bd2
commit 373ed28445
2449 changed files with 53602 additions and 0 deletions

View 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]]()