Home Assistant Unofficial Reference 2024.12.1
lock.py
Go to the documentation of this file.
1 """Lock for Yale Alarm."""
2 
3 from __future__ import annotations
4 
5 from typing import Any
6 
7 from yalesmartalarmclient import YaleLock, YaleLockState
8 
9 from homeassistant.components.lock import LockEntity, LockState
10 from homeassistant.const import ATTR_CODE
11 from homeassistant.core import HomeAssistant
12 from homeassistant.exceptions import HomeAssistantError, ServiceValidationError
13 from homeassistant.helpers.entity_platform import AddEntitiesCallback
14 
15 from . import YaleConfigEntry
16 from .const import (
17  CONF_LOCK_CODE_DIGITS,
18  DEFAULT_LOCK_CODE_DIGITS,
19  DOMAIN,
20  YALE_ALL_ERRORS,
21 )
22 from .coordinator import YaleDataUpdateCoordinator
23 from .entity import YaleLockEntity
24 
25 LOCK_STATE_MAP = {
26  YaleLockState.LOCKED: LockState.LOCKED,
27  YaleLockState.UNLOCKED: LockState.UNLOCKED,
28  YaleLockState.DOOR_OPEN: LockState.OPEN,
29 }
30 
31 
33  hass: HomeAssistant, entry: YaleConfigEntry, async_add_entities: AddEntitiesCallback
34 ) -> None:
35  """Set up the Yale lock entry."""
36 
37  coordinator = entry.runtime_data
38  code_format = entry.options.get(CONF_LOCK_CODE_DIGITS, DEFAULT_LOCK_CODE_DIGITS)
39 
41  YaleDoorlock(coordinator, lock, code_format) for lock in coordinator.locks
42  )
43 
44 
46  """Representation of a Yale doorlock."""
47 
48  _attr_name = None
49 
50  def __init__(
51  self, coordinator: YaleDataUpdateCoordinator, lock: YaleLock, code_format: int
52  ) -> None:
53  """Initialize the Yale Lock Device."""
54  super().__init__(coordinator, lock)
55  self._attr_code_format_attr_code_format = rf"^\d{{{code_format}}}$"
56 
57  async def async_unlock(self, **kwargs: Any) -> None:
58  """Send unlock command."""
59  code: str | None = kwargs.get(ATTR_CODE)
60  return await self.async_set_lockasync_set_lock(YaleLockState.UNLOCKED, code)
61 
62  async def async_lock(self, **kwargs: Any) -> None:
63  """Send lock command."""
64  return await self.async_set_lockasync_set_lock(YaleLockState.LOCKED, None)
65 
66  async def async_set_lock(self, state: YaleLockState, code: str | None) -> None:
67  """Set lock."""
68  if state is YaleLockState.UNLOCKED and not code:
70  translation_domain=DOMAIN,
71  translation_key="no_code",
72  )
73 
74  lock_state = False
75  try:
76  if state is YaleLockState.LOCKED:
77  lock_state = await self.hasshasshass.async_add_executor_job(
78  self.lock_datalock_data.close
79  )
80  if code and state is YaleLockState.UNLOCKED:
81  lock_state = await self.hasshasshass.async_add_executor_job(
82  self.lock_datalock_data.open, code
83  )
84  except YALE_ALL_ERRORS as error:
85  raise HomeAssistantError(
86  translation_domain=DOMAIN,
87  translation_key="set_lock",
88  translation_placeholders={
89  "name": self.lock_datalock_data.name,
90  "error": str(error),
91  },
92  ) from error
93 
94  if lock_state:
95  self.lock_datalock_data.set_state(state)
96  self.async_write_ha_stateasync_write_ha_state()
97  return
98  raise HomeAssistantError(
99  translation_domain=DOMAIN,
100  translation_key="could_not_change_lock",
101  )
102 
103  @property
104  def is_locked(self) -> bool | None:
105  """Return true if the lock is locked."""
106  return LOCK_STATE_MAP.get(self.lock_datalock_data.state()) == LockState.LOCKED
107 
108  @property
109  def is_open(self) -> bool | None:
110  """Return true if the lock is open."""
111  return LOCK_STATE_MAP.get(self.lock_datalock_data.state()) == LockState.OPEN
None async_set_lock(self, YaleLockState state, str|None code)
Definition: lock.py:66
None __init__(self, YaleDataUpdateCoordinator coordinator, YaleLock lock, int code_format)
Definition: lock.py:52
None async_setup_entry(HomeAssistant hass, YaleConfigEntry entry, AddEntitiesCallback async_add_entities)
Definition: lock.py:34