mirror of https://github.com/home-assistant/core
116 lines
3.9 KiB
Python
116 lines
3.9 KiB
Python
"""Base class for August entity."""
|
|
|
|
from abc import abstractmethod
|
|
|
|
from yalexs.activity import Activity, ActivityType
|
|
from yalexs.doorbell import Doorbell, DoorbellDetail
|
|
from yalexs.keypad import KeypadDetail
|
|
from yalexs.lock import Lock, LockDetail
|
|
from yalexs.util import get_configuration_url
|
|
|
|
from homeassistant.const import ATTR_CONNECTIONS
|
|
from homeassistant.core import callback
|
|
from homeassistant.helpers import device_registry as dr
|
|
from homeassistant.helpers.device_registry import DeviceInfo
|
|
from homeassistant.helpers.entity import Entity, EntityDescription
|
|
|
|
from . import DOMAIN, AugustData
|
|
from .const import MANUFACTURER
|
|
|
|
DEVICE_TYPES = ["keypad", "lock", "camera", "doorbell", "door", "bell"]
|
|
|
|
|
|
class AugustEntity(Entity):
|
|
"""Base implementation for August device."""
|
|
|
|
_attr_should_poll = False
|
|
_attr_has_entity_name = True
|
|
|
|
def __init__(
|
|
self, data: AugustData, device: Doorbell | Lock | KeypadDetail, unique_id: str
|
|
) -> None:
|
|
"""Initialize an August device."""
|
|
super().__init__()
|
|
self._data = data
|
|
self._stream = data.activity_stream
|
|
self._device = device
|
|
detail = self._detail
|
|
self._device_id = device.device_id
|
|
self._attr_unique_id = f"{device.device_id}_{unique_id}"
|
|
self._attr_device_info = DeviceInfo(
|
|
identifiers={(DOMAIN, self._device_id)},
|
|
manufacturer=MANUFACTURER,
|
|
model=detail.model,
|
|
name=device.device_name,
|
|
sw_version=detail.firmware_version,
|
|
suggested_area=_remove_device_types(device.device_name, DEVICE_TYPES),
|
|
configuration_url=get_configuration_url(data.brand),
|
|
)
|
|
if isinstance(detail, LockDetail) and (mac := detail.mac_address):
|
|
self._attr_device_info[ATTR_CONNECTIONS] = {(dr.CONNECTION_BLUETOOTH, mac)}
|
|
|
|
@property
|
|
def _detail(self) -> DoorbellDetail | LockDetail:
|
|
return self._data.get_device_detail(self._device.device_id)
|
|
|
|
@property
|
|
def _hyper_bridge(self) -> bool:
|
|
"""Check if the lock has a paired hyper bridge."""
|
|
return bool(self._detail.bridge and self._detail.bridge.hyper_bridge)
|
|
|
|
@callback
|
|
def _get_latest(self, activity_types: set[ActivityType]) -> Activity | None:
|
|
"""Get the latest activity for the device."""
|
|
return self._stream.get_latest_device_activity(self._device_id, activity_types)
|
|
|
|
@callback
|
|
def _update_from_data_and_write_state(self) -> None:
|
|
self._update_from_data()
|
|
self.async_write_ha_state()
|
|
|
|
@abstractmethod
|
|
def _update_from_data(self) -> None:
|
|
"""Update the entity state from the data object."""
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
"""Subscribe to updates."""
|
|
self.async_on_remove(
|
|
self._data.async_subscribe_device_id(
|
|
self._device_id, self._update_from_data_and_write_state
|
|
)
|
|
)
|
|
self.async_on_remove(
|
|
self._stream.async_subscribe_device_id(
|
|
self._device_id, self._update_from_data_and_write_state
|
|
)
|
|
)
|
|
self._update_from_data()
|
|
|
|
|
|
class AugustDescriptionEntity(AugustEntity):
|
|
"""An August entity with a description."""
|
|
|
|
def __init__(
|
|
self,
|
|
data: AugustData,
|
|
device: Doorbell | Lock | KeypadDetail,
|
|
description: EntityDescription,
|
|
) -> None:
|
|
"""Initialize an August entity with a description."""
|
|
super().__init__(data, device, description.key)
|
|
self.entity_description = description
|
|
|
|
|
|
def _remove_device_types(name: str, device_types: list[str]) -> str:
|
|
"""Strip device types from a string.
|
|
|
|
August stores the name as Master Bed Lock
|
|
or Master Bed Door. We can come up with a
|
|
reasonable suggestion by removing the supported
|
|
device types from the string.
|
|
"""
|
|
lower_name = name.lower()
|
|
for device_type in device_types:
|
|
lower_name = lower_name.removesuffix(f" {device_type}")
|
|
return name[: len(lower_name)]
|