1 """Support for Yale sensors."""
3 from __future__
import annotations
5 from collections.abc
import Callable
6 from dataclasses
import dataclass
7 from typing
import Any, cast
9 from yalexs.activity
import ActivityType, LockOperationActivity
10 from yalexs.doorbell
import Doorbell
11 from yalexs.keypad
import KeypadDetail
12 from yalexs.lock
import LockDetail
18 SensorEntityDescription,
30 from .
import YaleConfigEntry
32 ATTR_OPERATION_AUTORELOCK,
33 ATTR_OPERATION_KEYPAD,
34 ATTR_OPERATION_MANUAL,
35 ATTR_OPERATION_METHOD,
36 ATTR_OPERATION_REMOTE,
38 OPERATION_METHOD_AUTORELOCK,
39 OPERATION_METHOD_KEYPAD,
40 OPERATION_METHOD_MANUAL,
41 OPERATION_METHOD_MOBILE_DEVICE,
42 OPERATION_METHOD_REMOTE,
45 from .entity
import YaleDescriptionEntity, YaleEntity
49 """Get the latest state of the sensor."""
50 return detail.battery_level
54 """Get the latest state of the sensor."""
55 return detail.battery_percentage
58 @dataclass(frozen=True, kw_only=True)
60 SensorEntityDescription
62 """Mixin for required keys."""
64 value_fn: Callable[[T], int |
None]
67 SENSOR_TYPE_DEVICE_BATTERY = YaleSensorEntityDescription[LockDetail](
69 entity_category=EntityCategory.DIAGNOSTIC,
70 state_class=SensorStateClass.MEASUREMENT,
71 value_fn=_retrieve_device_battery_state,
74 SENSOR_TYPE_KEYPAD_BATTERY = YaleSensorEntityDescription[KeypadDetail](
75 key=
"linked_keypad_battery",
76 entity_category=EntityCategory.DIAGNOSTIC,
77 state_class=SensorStateClass.MEASUREMENT,
78 value_fn=_retrieve_linked_keypad_battery_state,
84 config_entry: YaleConfigEntry,
85 async_add_entities: AddEntitiesCallback,
87 """Set up the Yale sensors."""
88 data = config_entry.runtime_data
89 entities: list[SensorEntity] = []
91 for device
in data.locks:
92 detail = data.get_device_detail(device.device_id)
94 if SENSOR_TYPE_DEVICE_BATTERY.value_fn(detail):
96 YaleBatterySensor[LockDetail](data, device, SENSOR_TYPE_DEVICE_BATTERY)
98 if keypad := detail.keypad:
100 YaleBatterySensor[KeypadDetail](
101 data, keypad, SENSOR_TYPE_KEYPAD_BATTERY
106 YaleBatterySensor[Doorbell](data, device, SENSOR_TYPE_DEVICE_BATTERY)
107 for device
in data.doorbells
108 if SENSOR_TYPE_DEVICE_BATTERY.value_fn(data.get_device_detail(device.device_id))
115 """Representation of an Yale lock operation sensor."""
117 _attr_translation_key =
"operator"
118 _operated_remote: bool |
None =
None
119 _operated_keypad: bool |
None =
None
120 _operated_manual: bool |
None =
None
121 _operated_tag: bool |
None =
None
122 _operated_autorelock: bool |
None =
None
126 """Get the latest state of the sensor and update activity."""
128 if lock_activity := self.
_get_latest_get_latest({ActivityType.LOCK_OPERATION}):
129 lock_activity = cast(LockOperationActivity, lock_activity)
140 """Return the device specific state attributes."""
141 attributes: dict[str, Any] = {}
150 attributes[ATTR_OPERATION_TAG] = self.
_operated_tag_operated_tag
155 attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_REMOTE
157 attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_KEYPAD
159 attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_MANUAL
161 attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_TAG
163 attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_AUTORELOCK
165 attributes[ATTR_OPERATION_METHOD] = OPERATION_METHOD_MOBILE_DEVICE
170 """Restore ATTR_CHANGED_BY on startup since it is likely no longer in the activity log."""
173 last_state = await self.async_get_last_state()
177 or not last_sensor_state
178 or last_state.state == STATE_UNAVAILABLE
183 last_attrs = last_state.attributes
184 if ATTR_ENTITY_PICTURE
in last_attrs:
186 if ATTR_OPERATION_REMOTE
in last_attrs:
188 if ATTR_OPERATION_KEYPAD
in last_attrs:
190 if ATTR_OPERATION_MANUAL
in last_attrs:
192 if ATTR_OPERATION_TAG
in last_attrs:
193 self.
_operated_tag_operated_tag = last_attrs[ATTR_OPERATION_TAG]
194 if ATTR_OPERATION_AUTORELOCK
in last_attrs:
199 YaleDescriptionEntity, SensorEntity
201 """Representation of an Yale sensor."""
203 entity_description: YaleSensorEntityDescription[T]
204 _attr_device_class = SensorDeviceClass.BATTERY
205 _attr_native_unit_of_measurement = PERCENTAGE
209 """Get the latest state of the sensor."""
210 self._attr_native_value = self.entity_description.
value_fn(self._detail)
211 self._attr_available = self._attr_native_value
is not None
SensorExtraStoredData|None async_get_last_sensor_data(self)
Activity|None _get_latest(self, set[ActivityType] activity_types)
None async_added_to_hass(self)
None _update_from_data(self)
dict[str, Any] extra_state_attributes(self)
int|None _retrieve_linked_keypad_battery_state(KeypadDetail detail)
None async_setup_entry(HomeAssistant hass, YaleConfigEntry config_entry, AddEntitiesCallback async_add_entities)
None _update_from_data(self)
int _retrieve_device_battery_state(LockDetail detail)