core/homeassistant/components/tedee/lock.py

151 lines
4.9 KiB
Python

"""Tedee lock entities."""
from typing import Any
from aiotedee import TedeeClientException, TedeeLock, TedeeLockState
from homeassistant.components.lock import LockEntity, LockEntityFeature
from homeassistant.core import HomeAssistant
from homeassistant.exceptions import HomeAssistantError
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from .const import DOMAIN
from .coordinator import TedeeApiCoordinator, TedeeConfigEntry
from .entity import TedeeEntity
PARALLEL_UPDATES = 1
async def async_setup_entry(
hass: HomeAssistant,
entry: TedeeConfigEntry,
async_add_entities: AddEntitiesCallback,
) -> None:
"""Set up the Tedee lock entity."""
coordinator = entry.runtime_data
def _async_add_new_lock(locks: list[TedeeLock]) -> None:
entities: list[TedeeLockEntity] = []
for lock in locks:
if lock.is_enabled_pullspring:
entities.append(TedeeLockWithLatchEntity(lock, coordinator))
else:
entities.append(TedeeLockEntity(lock, coordinator))
async_add_entities(entities)
coordinator.new_lock_callbacks.append(_async_add_new_lock)
_async_add_new_lock(list(coordinator.data.values()))
class TedeeLockEntity(TedeeEntity, LockEntity):
"""A tedee lock that doesn't have pullspring enabled."""
_attr_name = None
def __init__(
self,
lock: TedeeLock,
coordinator: TedeeApiCoordinator,
) -> None:
"""Initialize the lock."""
super().__init__(lock, coordinator, "lock")
@property
def is_locked(self) -> bool | None:
"""Return true if lock is locked."""
if self._lock.state in (
TedeeLockState.HALF_OPEN,
TedeeLockState.UNKNOWN,
):
return None
return self._lock.state == TedeeLockState.LOCKED
@property
def is_unlocking(self) -> bool:
"""Return true if lock is unlocking."""
return self._lock.state == TedeeLockState.UNLOCKING
@property
def is_open(self) -> bool:
"""Return true if lock is open."""
return self._lock.state == TedeeLockState.PULLED
@property
def is_opening(self) -> bool:
"""Return true if lock is opening."""
return self._lock.state == TedeeLockState.PULLING
@property
def is_locking(self) -> bool:
"""Return true if lock is locking."""
return self._lock.state == TedeeLockState.LOCKING
@property
def is_jammed(self) -> bool:
"""Return true if lock is jammed."""
return self._lock.is_state_jammed
@property
def available(self) -> bool:
"""Return True if entity is available."""
return (
super().available
and self._lock.is_connected
and self._lock.state != TedeeLockState.UNCALIBRATED
)
async def async_unlock(self, **kwargs: Any) -> None:
"""Unlock the door."""
try:
self._lock.state = TedeeLockState.UNLOCKING
self.async_write_ha_state()
await self.coordinator.tedee_client.unlock(self._lock.lock_id)
await self.coordinator.async_request_refresh()
except (TedeeClientException, Exception) as ex:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="unlock_failed",
translation_placeholders={"lock_id": str(self._lock.lock_id)},
) from ex
async def async_lock(self, **kwargs: Any) -> None:
"""Lock the door."""
try:
self._lock.state = TedeeLockState.LOCKING
self.async_write_ha_state()
await self.coordinator.tedee_client.lock(self._lock.lock_id)
await self.coordinator.async_request_refresh()
except (TedeeClientException, Exception) as ex:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="lock_failed",
translation_placeholders={"lock_id": str(self._lock.lock_id)},
) from ex
class TedeeLockWithLatchEntity(TedeeLockEntity):
"""A tedee lock but has pullspring enabled, so it additional features."""
@property
def supported_features(self) -> LockEntityFeature:
"""Flag supported features."""
return LockEntityFeature.OPEN
async def async_open(self, **kwargs: Any) -> None:
"""Open the door with pullspring."""
try:
self._lock.state = TedeeLockState.UNLOCKING
self.async_write_ha_state()
await self.coordinator.tedee_client.open(self._lock.lock_id)
await self.coordinator.async_request_refresh()
except (TedeeClientException, Exception) as ex:
raise HomeAssistantError(
translation_domain=DOMAIN,
translation_key="open_failed",
translation_placeholders={"lock_id": str(self._lock.lock_id)},
) from ex