1 """Support for Yale lock."""
3 from __future__
import annotations
5 from collections.abc
import Callable, Coroutine
9 from aiohttp
import ClientResponseError
10 from yalexs.activity
import ActivityType, ActivityTypes
11 from yalexs.lock
import Lock, LockStatus
12 from yalexs.util
import get_latest_activity, update_lock_detail_from_activity
21 from .
import YaleConfigEntry, YaleData
22 from .entity
import YaleEntity
24 _LOGGER = logging.getLogger(__name__)
31 config_entry: YaleConfigEntry,
32 async_add_entities: AddEntitiesCallback,
34 """Set up Yale locks."""
35 data = config_entry.runtime_data
40 """Representation of an Yale lock."""
43 _lock_status: LockStatus |
None =
None
45 def __init__(self, data: YaleData, device: Lock) ->
None:
46 """Initialize the lock."""
47 super().
__init__(data, device,
"lock")
48 if self.
_detail_detail.unlatch_supported:
52 """Lock the device."""
53 if self.
_data_data.push_updates_connected:
59 """Open/unlatch the device."""
60 if self.
_data_data.push_updates_connected:
66 """Unlock the device."""
67 if self.
_data_data.push_updates_connected:
73 self, lock_operation: Callable[[str], Coroutine[Any, Any, list[ActivityTypes]]]
76 activities = await lock_operation(self.
_device_id_device_id)
77 except ClientResponseError
as err:
78 if err.status == LOCK_JAMMED_ERR:
79 self.
_detail_detail.lock_status = LockStatus.JAMMED
80 self.
_detail_detail.lock_status_datetime = dt_util.utcnow()
84 for lock_activity
in activities:
85 update_lock_detail_from_activity(self.
_detail_detail, lock_activity)
89 "async_signal_device_id_update (from lock operation): %s",
92 self.
_data_data.async_signal_device_id_update(self.
_device_id_device_id)
104 """Get the latest state of the sensor and update activity."""
106 if lock_activity := self.
_get_latest_get_latest({ActivityType.LOCK_OPERATION}):
108 lock_activity_without_operator = self.
_get_latest_get_latest(
109 {ActivityType.LOCK_OPERATION_WITHOUT_OPERATOR}
111 if latest_activity := get_latest_activity(
112 lock_activity_without_operator, lock_activity
114 if latest_activity.was_pushed:
115 self.
_detail_detail.set_online(
True)
116 update_lock_detail_from_activity(detail, latest_activity)
118 if bridge_activity := self.
_get_latest_get_latest({ActivityType.BRIDGE_OPERATION}):
119 update_lock_detail_from_activity(detail, bridge_activity)
123 if lock_status
is None or lock_status
is LockStatus.UNKNOWN:
130 LockStatus.UNLOCKING,
131 LockStatus.UNLATCHING,
134 if keypad := detail.keypad:
140 """Restore ATTR_CHANGED_BY on startup since it is likely no longer in the activity log."""
146 if ATTR_CHANGED_BY
in last_state.attributes:
147 self.
_attr_changed_by_attr_changed_by = last_state.attributes[ATTR_CHANGED_BY]
DoorbellDetail|LockDetail _detail(self)
Activity|None _get_latest(self, set[ActivityType] activity_types)
None async_lock(self, **Any kwargs)
None async_unlock(self, **Any kwargs)
None async_added_to_hass(self)
None _call_lock_operation(self, Callable[[str], Coroutine[Any, Any, list[ActivityTypes]]] lock_operation)
None _update_from_data(self)
None async_open(self, **Any kwargs)
None __init__(self, YaleData data, Lock device)
bool _update_lock_status_from_detail(self)
_attr_extra_state_attributes
State|None async_get_last_state(self)
None async_setup_entry(HomeAssistant hass, YaleConfigEntry config_entry, AddEntitiesCallback async_add_entities)