mirror of
https://github.com/home-assistant/core.git
synced 2025-07-29 08:07:45 +00:00
Small cleanups to august (#119950)
This commit is contained in:
parent
52bc006a72
commit
87e52bb660
@ -11,7 +11,7 @@ from yalexs.manager.exceptions import CannotConnect, InvalidAuth, RequireValidat
|
|||||||
from yalexs.manager.gateway import Config as YaleXSConfig
|
from yalexs.manager.gateway import Config as YaleXSConfig
|
||||||
|
|
||||||
from homeassistant.config_entries import ConfigEntry
|
from homeassistant.config_entries import ConfigEntry
|
||||||
from homeassistant.const import CONF_PASSWORD, EVENT_HOMEASSISTANT_STOP
|
from homeassistant.const import EVENT_HOMEASSISTANT_STOP
|
||||||
from homeassistant.core import HomeAssistant
|
from homeassistant.core import HomeAssistant
|
||||||
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
from homeassistant.exceptions import ConfigEntryAuthFailed, ConfigEntryNotReady
|
||||||
from homeassistant.helpers import device_registry as dr
|
from homeassistant.helpers import device_registry as dr
|
||||||
@ -29,13 +29,15 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
|
|||||||
session = async_create_august_clientsession(hass)
|
session = async_create_august_clientsession(hass)
|
||||||
august_gateway = AugustGateway(Path(hass.config.config_dir), session)
|
august_gateway = AugustGateway(Path(hass.config.config_dir), session)
|
||||||
try:
|
try:
|
||||||
return await async_setup_august(hass, entry, august_gateway)
|
await async_setup_august(hass, entry, august_gateway)
|
||||||
except (RequireValidation, InvalidAuth) as err:
|
except (RequireValidation, InvalidAuth) as err:
|
||||||
raise ConfigEntryAuthFailed from err
|
raise ConfigEntryAuthFailed from err
|
||||||
except TimeoutError as err:
|
except TimeoutError as err:
|
||||||
raise ConfigEntryNotReady("Timed out connecting to august api") from err
|
raise ConfigEntryNotReady("Timed out connecting to august api") from err
|
||||||
except (AugustApiAIOHTTPError, ClientResponseError, CannotConnect) as err:
|
except (AugustApiAIOHTTPError, ClientResponseError, CannotConnect) as err:
|
||||||
raise ConfigEntryNotReady from err
|
raise ConfigEntryNotReady from err
|
||||||
|
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
async def async_unload_entry(hass: HomeAssistant, entry: AugustConfigEntry) -> bool:
|
async def async_unload_entry(hass: HomeAssistant, entry: AugustConfigEntry) -> bool:
|
||||||
@ -45,32 +47,19 @@ async def async_unload_entry(hass: HomeAssistant, entry: AugustConfigEntry) -> b
|
|||||||
|
|
||||||
async def async_setup_august(
|
async def async_setup_august(
|
||||||
hass: HomeAssistant, entry: AugustConfigEntry, august_gateway: AugustGateway
|
hass: HomeAssistant, entry: AugustConfigEntry, august_gateway: AugustGateway
|
||||||
) -> bool:
|
) -> None:
|
||||||
"""Set up the August component."""
|
"""Set up the August component."""
|
||||||
config = cast(YaleXSConfig, entry.data)
|
config = cast(YaleXSConfig, entry.data)
|
||||||
await august_gateway.async_setup(config)
|
await august_gateway.async_setup(config)
|
||||||
|
|
||||||
if CONF_PASSWORD in entry.data:
|
|
||||||
# We no longer need to store passwords since we do not
|
|
||||||
# support YAML anymore
|
|
||||||
config_data = entry.data.copy()
|
|
||||||
del config_data[CONF_PASSWORD]
|
|
||||||
hass.config_entries.async_update_entry(entry, data=config_data)
|
|
||||||
|
|
||||||
await august_gateway.async_authenticate()
|
await august_gateway.async_authenticate()
|
||||||
await august_gateway.async_refresh_access_token_if_needed()
|
await august_gateway.async_refresh_access_token_if_needed()
|
||||||
|
data = entry.runtime_data = AugustData(hass, august_gateway)
|
||||||
data = entry.runtime_data = AugustData(hass, entry, august_gateway)
|
|
||||||
entry.async_on_unload(
|
entry.async_on_unload(
|
||||||
hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, data.async_stop)
|
hass.bus.async_listen(EVENT_HOMEASSISTANT_STOP, data.async_stop)
|
||||||
)
|
)
|
||||||
entry.async_on_unload(data.async_stop)
|
entry.async_on_unload(data.async_stop)
|
||||||
await data.async_setup()
|
await data.async_setup()
|
||||||
|
|
||||||
await hass.config_entries.async_forward_entry_setups(entry, PLATFORMS)
|
|
||||||
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
async def async_remove_config_entry_device(
|
async def async_remove_config_entry_device(
|
||||||
hass: HomeAssistant, config_entry: AugustConfigEntry, device_entry: dr.DeviceEntry
|
hass: HomeAssistant, config_entry: AugustConfigEntry, device_entry: dr.DeviceEntry
|
||||||
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||||||
from collections.abc import Callable
|
from collections.abc import Callable
|
||||||
from dataclasses import dataclass
|
from dataclasses import dataclass
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
from functools import partial
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from yalexs.activity import (
|
from yalexs.activity import (
|
||||||
@ -51,28 +52,14 @@ def _retrieve_online_state(
|
|||||||
return detail.bridge_is_online
|
return detail.bridge_is_online
|
||||||
|
|
||||||
|
|
||||||
def _retrieve_motion_state(data: AugustData, detail: DoorbellDetail) -> bool:
|
def _retrieve_time_based_state(
|
||||||
assert data.activity_stream is not None
|
activities: set[ActivityType], data: AugustData, detail: DoorbellDetail
|
||||||
latest = data.activity_stream.get_latest_device_activity(
|
) -> bool:
|
||||||
detail.device_id, {ActivityType.DOORBELL_MOTION}
|
"""Get the latest state of the sensor."""
|
||||||
)
|
|
||||||
|
|
||||||
if latest is None:
|
|
||||||
return False
|
|
||||||
|
|
||||||
return _activity_time_based_state(latest)
|
|
||||||
|
|
||||||
|
|
||||||
_IMAGE_ACTIVITIES = {ActivityType.DOORBELL_IMAGE_CAPTURE}
|
|
||||||
|
|
||||||
|
|
||||||
def _retrieve_image_capture_state(data: AugustData, detail: DoorbellDetail) -> bool:
|
|
||||||
stream = data.activity_stream
|
stream = data.activity_stream
|
||||||
assert stream is not None
|
if latest := stream.get_latest_device_activity(detail.device_id, activities):
|
||||||
latest = stream.get_latest_device_activity(detail.device_id, _IMAGE_ACTIVITIES)
|
return _activity_time_based_state(latest)
|
||||||
if latest is None:
|
return False
|
||||||
return False
|
|
||||||
return _activity_time_based_state(latest)
|
|
||||||
|
|
||||||
|
|
||||||
_RING_ACTIVITIES = {ActivityType.DOORBELL_DING}
|
_RING_ACTIVITIES = {ActivityType.DOORBELL_DING}
|
||||||
@ -80,7 +67,6 @@ _RING_ACTIVITIES = {ActivityType.DOORBELL_DING}
|
|||||||
|
|
||||||
def _retrieve_ding_state(data: AugustData, detail: DoorbellDetail | LockDetail) -> bool:
|
def _retrieve_ding_state(data: AugustData, detail: DoorbellDetail | LockDetail) -> bool:
|
||||||
stream = data.activity_stream
|
stream = data.activity_stream
|
||||||
assert stream is not None
|
|
||||||
latest = stream.get_latest_device_activity(detail.device_id, _RING_ACTIVITIES)
|
latest = stream.get_latest_device_activity(detail.device_id, _RING_ACTIVITIES)
|
||||||
if latest is None or (
|
if latest is None or (
|
||||||
data.push_updates_connected and latest.action == ACTION_DOORBELL_CALL_MISSED
|
data.push_updates_connected and latest.action == ACTION_DOORBELL_CALL_MISSED
|
||||||
@ -118,13 +104,15 @@ SENSOR_TYPES_VIDEO_DOORBELL = (
|
|||||||
AugustDoorbellBinarySensorEntityDescription(
|
AugustDoorbellBinarySensorEntityDescription(
|
||||||
key="motion",
|
key="motion",
|
||||||
device_class=BinarySensorDeviceClass.MOTION,
|
device_class=BinarySensorDeviceClass.MOTION,
|
||||||
value_fn=_retrieve_motion_state,
|
value_fn=partial(_retrieve_time_based_state, {ActivityType.DOORBELL_MOTION}),
|
||||||
is_time_based=True,
|
is_time_based=True,
|
||||||
),
|
),
|
||||||
AugustDoorbellBinarySensorEntityDescription(
|
AugustDoorbellBinarySensorEntityDescription(
|
||||||
key="image capture",
|
key="image capture",
|
||||||
translation_key="image_capture",
|
translation_key="image_capture",
|
||||||
value_fn=_retrieve_image_capture_state,
|
value_fn=partial(
|
||||||
|
_retrieve_time_based_state, {ActivityType.DOORBELL_IMAGE_CAPTURE}
|
||||||
|
),
|
||||||
is_time_based=True,
|
is_time_based=True,
|
||||||
),
|
),
|
||||||
AugustDoorbellBinarySensorEntityDescription(
|
AugustDoorbellBinarySensorEntityDescription(
|
||||||
@ -185,22 +173,13 @@ class AugustDoorBinarySensor(AugustDescriptionEntity, BinarySensorEntity):
|
|||||||
@callback
|
@callback
|
||||||
def _update_from_data(self) -> None:
|
def _update_from_data(self) -> None:
|
||||||
"""Get the latest state of the sensor and update activity."""
|
"""Get the latest state of the sensor and update activity."""
|
||||||
assert self._data.activity_stream is not None
|
if door_activity := self._get_latest({ActivityType.DOOR_OPERATION}):
|
||||||
door_activity = self._data.activity_stream.get_latest_device_activity(
|
|
||||||
self._device_id, {ActivityType.DOOR_OPERATION}
|
|
||||||
)
|
|
||||||
|
|
||||||
if door_activity is not None:
|
|
||||||
update_lock_detail_from_activity(self._detail, door_activity)
|
update_lock_detail_from_activity(self._detail, door_activity)
|
||||||
# If the source is pubnub the lock must be online since its a live update
|
# If the source is pubnub the lock must be online since its a live update
|
||||||
if door_activity.source == SOURCE_PUBNUB:
|
if door_activity.source == SOURCE_PUBNUB:
|
||||||
self._detail.set_online(True)
|
self._detail.set_online(True)
|
||||||
|
|
||||||
bridge_activity = self._data.activity_stream.get_latest_device_activity(
|
if bridge_activity := self._get_latest({ActivityType.BRIDGE_OPERATION}):
|
||||||
self._device_id, {ActivityType.BRIDGE_OPERATION}
|
|
||||||
)
|
|
||||||
|
|
||||||
if bridge_activity is not None:
|
|
||||||
update_lock_detail_from_activity(self._detail, bridge_activity)
|
update_lock_detail_from_activity(self._detail, bridge_activity)
|
||||||
self._attr_available = self._detail.bridge_is_online
|
self._attr_available = self._detail.bridge_is_online
|
||||||
self._attr_is_on = self._detail.door_state == LockDoorStatus.OPEN
|
self._attr_is_on = self._detail.door_state == LockDoorStatus.OPEN
|
||||||
|
@ -54,17 +54,13 @@ class AugustCamera(AugustEntityMixin, Camera):
|
|||||||
super().__init__(data, device, "camera")
|
super().__init__(data, device, "camera")
|
||||||
self._timeout = timeout
|
self._timeout = timeout
|
||||||
self._session = session
|
self._session = session
|
||||||
|
self._attr_model = self._detail.model
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_recording(self) -> bool:
|
def is_recording(self) -> bool:
|
||||||
"""Return true if the device is recording."""
|
"""Return true if the device is recording."""
|
||||||
return self._device.has_subscription
|
return self._device.has_subscription
|
||||||
|
|
||||||
@property
|
|
||||||
def model(self) -> str | None:
|
|
||||||
"""Return the camera model."""
|
|
||||||
return self._detail.model
|
|
||||||
|
|
||||||
async def _async_update(self):
|
async def _async_update(self):
|
||||||
"""Update device."""
|
"""Update device."""
|
||||||
_LOGGER.debug("async_update called %s", self._detail.device_name)
|
_LOGGER.debug("async_update called %s", self._detail.device_name)
|
||||||
@ -74,11 +70,9 @@ class AugustCamera(AugustEntityMixin, Camera):
|
|||||||
@callback
|
@callback
|
||||||
def _update_from_data(self) -> None:
|
def _update_from_data(self) -> None:
|
||||||
"""Get the latest state of the sensor."""
|
"""Get the latest state of the sensor."""
|
||||||
doorbell_activity = self._data.activity_stream.get_latest_device_activity(
|
if doorbell_activity := self._get_latest(
|
||||||
self._device_id,
|
{ActivityType.DOORBELL_MOTION, ActivityType.DOORBELL_IMAGE_CAPTURE}
|
||||||
{ActivityType.DOORBELL_MOTION, ActivityType.DOORBELL_IMAGE_CAPTURE},
|
):
|
||||||
)
|
|
||||||
if doorbell_activity is not None:
|
|
||||||
update_doorbell_image_from_activity(self._detail, doorbell_activity)
|
update_doorbell_image_from_activity(self._detail, doorbell_activity)
|
||||||
|
|
||||||
async def async_camera_image(
|
async def async_camera_image(
|
||||||
|
@ -6,7 +6,7 @@ from yalexs.lock import LockDetail
|
|||||||
from yalexs.manager.data import YaleXSData
|
from yalexs.manager.data import YaleXSData
|
||||||
from yalexs_ble import YaleXSBLEDiscovery
|
from yalexs_ble import YaleXSBLEDiscovery
|
||||||
|
|
||||||
from homeassistant.config_entries import SOURCE_INTEGRATION_DISCOVERY, ConfigEntry
|
from homeassistant.config_entries import SOURCE_INTEGRATION_DISCOVERY
|
||||||
from homeassistant.core import HomeAssistant, callback
|
from homeassistant.core import HomeAssistant, callback
|
||||||
from homeassistant.exceptions import HomeAssistantError
|
from homeassistant.exceptions import HomeAssistantError
|
||||||
from homeassistant.helpers import discovery_flow
|
from homeassistant.helpers import discovery_flow
|
||||||
@ -41,12 +41,7 @@ def _async_trigger_ble_lock_discovery(
|
|||||||
class AugustData(YaleXSData):
|
class AugustData(YaleXSData):
|
||||||
"""August data object."""
|
"""August data object."""
|
||||||
|
|
||||||
def __init__(
|
def __init__(self, hass: HomeAssistant, august_gateway: AugustGateway) -> None:
|
||||||
self,
|
|
||||||
hass: HomeAssistant,
|
|
||||||
config_entry: ConfigEntry,
|
|
||||||
august_gateway: AugustGateway,
|
|
||||||
) -> None:
|
|
||||||
"""Init August data object."""
|
"""Init August data object."""
|
||||||
self._hass = hass
|
self._hass = hass
|
||||||
super().__init__(august_gateway, HomeAssistantError)
|
super().__init__(august_gateway, HomeAssistantError)
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
|
|
||||||
|
from yalexs.activity import Activity, ActivityType
|
||||||
from yalexs.doorbell import Doorbell, DoorbellDetail
|
from yalexs.doorbell import Doorbell, DoorbellDetail
|
||||||
from yalexs.keypad import KeypadDetail
|
from yalexs.keypad import KeypadDetail
|
||||||
from yalexs.lock import Lock, LockDetail
|
from yalexs.lock import Lock, LockDetail
|
||||||
@ -31,8 +32,10 @@ class AugustEntityMixin(Entity):
|
|||||||
"""Initialize an August device."""
|
"""Initialize an August device."""
|
||||||
super().__init__()
|
super().__init__()
|
||||||
self._data = data
|
self._data = data
|
||||||
|
self._stream = data.activity_stream
|
||||||
self._device = device
|
self._device = device
|
||||||
detail = self._detail
|
detail = self._detail
|
||||||
|
self._device_id = device.device_id
|
||||||
self._attr_unique_id = f"{device.device_id}_{unique_id}"
|
self._attr_unique_id = f"{device.device_id}_{unique_id}"
|
||||||
self._attr_device_info = DeviceInfo(
|
self._attr_device_info = DeviceInfo(
|
||||||
identifiers={(DOMAIN, self._device_id)},
|
identifiers={(DOMAIN, self._device_id)},
|
||||||
@ -46,10 +49,6 @@ class AugustEntityMixin(Entity):
|
|||||||
if isinstance(detail, LockDetail) and (mac := detail.mac_address):
|
if isinstance(detail, LockDetail) and (mac := detail.mac_address):
|
||||||
self._attr_device_info[ATTR_CONNECTIONS] = {(dr.CONNECTION_BLUETOOTH, mac)}
|
self._attr_device_info[ATTR_CONNECTIONS] = {(dr.CONNECTION_BLUETOOTH, mac)}
|
||||||
|
|
||||||
@property
|
|
||||||
def _device_id(self) -> str:
|
|
||||||
return self._device.device_id
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def _detail(self) -> DoorbellDetail | LockDetail:
|
def _detail(self) -> DoorbellDetail | LockDetail:
|
||||||
return self._data.get_device_detail(self._device.device_id)
|
return self._data.get_device_detail(self._device.device_id)
|
||||||
@ -59,6 +58,11 @@ class AugustEntityMixin(Entity):
|
|||||||
"""Check if the lock has a paired hyper bridge."""
|
"""Check if the lock has a paired hyper bridge."""
|
||||||
return bool(self._detail.bridge and self._detail.bridge.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
|
@callback
|
||||||
def _update_from_data_and_write_state(self) -> None:
|
def _update_from_data_and_write_state(self) -> None:
|
||||||
self._update_from_data()
|
self._update_from_data()
|
||||||
@ -76,7 +80,7 @@ class AugustEntityMixin(Entity):
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
self.async_on_remove(
|
self.async_on_remove(
|
||||||
self._data.activity_stream.async_subscribe_device_id(
|
self._stream.async_subscribe_device_id(
|
||||||
self._device_id, self._update_from_data_and_write_state
|
self._device_id, self._update_from_data_and_write_state
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
@ -50,7 +50,6 @@ class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
|
|||||||
|
|
||||||
async def async_lock(self, **kwargs: Any) -> None:
|
async def async_lock(self, **kwargs: Any) -> None:
|
||||||
"""Lock the device."""
|
"""Lock the device."""
|
||||||
assert self._data.activity_stream is not None
|
|
||||||
if self._data.push_updates_connected:
|
if self._data.push_updates_connected:
|
||||||
await self._data.async_lock_async(self._device_id, self._hyper_bridge)
|
await self._data.async_lock_async(self._device_id, self._hyper_bridge)
|
||||||
return
|
return
|
||||||
@ -58,7 +57,6 @@ class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
|
|||||||
|
|
||||||
async def async_open(self, **kwargs: Any) -> None:
|
async def async_open(self, **kwargs: Any) -> None:
|
||||||
"""Open/unlatch the device."""
|
"""Open/unlatch the device."""
|
||||||
assert self._data.activity_stream is not None
|
|
||||||
if self._data.push_updates_connected:
|
if self._data.push_updates_connected:
|
||||||
await self._data.async_unlatch_async(self._device_id, self._hyper_bridge)
|
await self._data.async_unlatch_async(self._device_id, self._hyper_bridge)
|
||||||
return
|
return
|
||||||
@ -66,7 +64,6 @@ class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
|
|||||||
|
|
||||||
async def async_unlock(self, **kwargs: Any) -> None:
|
async def async_unlock(self, **kwargs: Any) -> None:
|
||||||
"""Unlock the device."""
|
"""Unlock the device."""
|
||||||
assert self._data.activity_stream is not None
|
|
||||||
if self._data.push_updates_connected:
|
if self._data.push_updates_connected:
|
||||||
await self._data.async_unlock_async(self._device_id, self._hyper_bridge)
|
await self._data.async_unlock_async(self._device_id, self._hyper_bridge)
|
||||||
return
|
return
|
||||||
@ -105,33 +102,22 @@ class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
|
|||||||
@callback
|
@callback
|
||||||
def _update_from_data(self) -> None:
|
def _update_from_data(self) -> None:
|
||||||
"""Get the latest state of the sensor and update activity."""
|
"""Get the latest state of the sensor and update activity."""
|
||||||
activity_stream = self._data.activity_stream
|
detail = self._detail
|
||||||
device_id = self._device_id
|
if lock_activity := self._get_latest({ActivityType.LOCK_OPERATION}):
|
||||||
if lock_activity := activity_stream.get_latest_device_activity(
|
|
||||||
device_id,
|
|
||||||
{ActivityType.LOCK_OPERATION},
|
|
||||||
):
|
|
||||||
self._attr_changed_by = lock_activity.operated_by
|
self._attr_changed_by = lock_activity.operated_by
|
||||||
|
lock_activity_without_operator = self._get_latest(
|
||||||
lock_activity_without_operator = activity_stream.get_latest_device_activity(
|
{ActivityType.LOCK_OPERATION_WITHOUT_OPERATOR}
|
||||||
device_id,
|
|
||||||
{ActivityType.LOCK_OPERATION_WITHOUT_OPERATOR},
|
|
||||||
)
|
)
|
||||||
|
|
||||||
if latest_activity := get_latest_activity(
|
if latest_activity := get_latest_activity(
|
||||||
lock_activity_without_operator, lock_activity
|
lock_activity_without_operator, lock_activity
|
||||||
):
|
):
|
||||||
if latest_activity.source == SOURCE_PUBNUB:
|
if latest_activity.source == SOURCE_PUBNUB:
|
||||||
# If the source is pubnub the lock must be online since its a live update
|
# If the source is pubnub the lock must be online since its a live update
|
||||||
self._detail.set_online(True)
|
self._detail.set_online(True)
|
||||||
update_lock_detail_from_activity(self._detail, latest_activity)
|
update_lock_detail_from_activity(detail, latest_activity)
|
||||||
|
|
||||||
bridge_activity = self._data.activity_stream.get_latest_device_activity(
|
if bridge_activity := self._get_latest({ActivityType.BRIDGE_OPERATION}):
|
||||||
self._device_id, {ActivityType.BRIDGE_OPERATION}
|
update_lock_detail_from_activity(detail, bridge_activity)
|
||||||
)
|
|
||||||
|
|
||||||
if bridge_activity is not None:
|
|
||||||
update_lock_detail_from_activity(self._detail, bridge_activity)
|
|
||||||
|
|
||||||
self._update_lock_status_from_detail()
|
self._update_lock_status_from_detail()
|
||||||
lock_status = self._lock_status
|
lock_status = self._lock_status
|
||||||
@ -139,20 +125,16 @@ class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
|
|||||||
self._attr_is_locked = None
|
self._attr_is_locked = None
|
||||||
else:
|
else:
|
||||||
self._attr_is_locked = lock_status is LockStatus.LOCKED
|
self._attr_is_locked = lock_status is LockStatus.LOCKED
|
||||||
|
|
||||||
self._attr_is_jammed = lock_status is LockStatus.JAMMED
|
self._attr_is_jammed = lock_status is LockStatus.JAMMED
|
||||||
self._attr_is_locking = lock_status is LockStatus.LOCKING
|
self._attr_is_locking = lock_status is LockStatus.LOCKING
|
||||||
self._attr_is_unlocking = lock_status in (
|
self._attr_is_unlocking = lock_status in (
|
||||||
LockStatus.UNLOCKING,
|
LockStatus.UNLOCKING,
|
||||||
LockStatus.UNLATCHING,
|
LockStatus.UNLATCHING,
|
||||||
)
|
)
|
||||||
|
self._attr_extra_state_attributes = {ATTR_BATTERY_LEVEL: detail.battery_level}
|
||||||
self._attr_extra_state_attributes = {
|
if keypad := detail.keypad:
|
||||||
ATTR_BATTERY_LEVEL: self._detail.battery_level
|
|
||||||
}
|
|
||||||
if self._detail.keypad is not None:
|
|
||||||
self._attr_extra_state_attributes["keypad_battery_level"] = (
|
self._attr_extra_state_attributes["keypad_battery_level"] = (
|
||||||
self._detail.keypad.battery_level
|
keypad.battery_level
|
||||||
)
|
)
|
||||||
|
|
||||||
async def async_added_to_hass(self) -> None:
|
async def async_added_to_hass(self) -> None:
|
||||||
|
@ -127,12 +127,8 @@ class AugustOperatorSensor(AugustEntityMixin, RestoreSensor):
|
|||||||
@callback
|
@callback
|
||||||
def _update_from_data(self) -> None:
|
def _update_from_data(self) -> None:
|
||||||
"""Get the latest state of the sensor and update activity."""
|
"""Get the latest state of the sensor and update activity."""
|
||||||
lock_activity = self._data.activity_stream.get_latest_device_activity(
|
|
||||||
self._device_id, {ActivityType.LOCK_OPERATION}
|
|
||||||
)
|
|
||||||
|
|
||||||
self._attr_available = True
|
self._attr_available = True
|
||||||
if lock_activity is not None:
|
if lock_activity := self._get_latest({ActivityType.LOCK_OPERATION}):
|
||||||
lock_activity = cast(LockOperationActivity, lock_activity)
|
lock_activity = cast(LockOperationActivity, lock_activity)
|
||||||
self._attr_native_value = lock_activity.operated_by
|
self._attr_native_value = lock_activity.operated_by
|
||||||
self._operated_remote = lock_activity.operated_remote
|
self._operated_remote = lock_activity.operated_remote
|
||||||
|
Loading…
x
Reference in New Issue
Block a user