mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Add button to wake august locks from deep sleep (#66343)
This commit is contained in:
parent
0797533016
commit
a6742eff34
39
homeassistant/components/august/button.py
Normal file
39
homeassistant/components/august/button.py
Normal file
@ -0,0 +1,39 @@
|
||||
"""Support for August buttons."""
|
||||
from yalexs.lock import Lock
|
||||
|
||||
from homeassistant.components.button import ButtonEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
||||
from . import AugustData
|
||||
from .const import DATA_AUGUST, DOMAIN
|
||||
from .entity import AugustEntityMixin
|
||||
|
||||
|
||||
async def async_setup_entry(
|
||||
hass: HomeAssistant,
|
||||
config_entry: ConfigEntry,
|
||||
async_add_entities: AddEntitiesCallback,
|
||||
) -> None:
|
||||
"""Set up August lock wake buttons."""
|
||||
data: AugustData = hass.data[DOMAIN][config_entry.entry_id][DATA_AUGUST]
|
||||
async_add_entities([AugustWakeLockButton(data, lock) for lock in data.locks])
|
||||
|
||||
|
||||
class AugustWakeLockButton(AugustEntityMixin, ButtonEntity):
|
||||
"""Representation of an August lock wake button."""
|
||||
|
||||
def __init__(self, data: AugustData, device: Lock) -> None:
|
||||
"""Initialize the lock wake button."""
|
||||
super().__init__(data, device)
|
||||
self._attr_name = f"{device.device_name} Wake"
|
||||
self._attr_unique_id = f"{self._device_id}_wake"
|
||||
|
||||
async def async_press(self, **kwargs):
|
||||
"""Wake the device."""
|
||||
await self._data.async_status_async(self._device_id, self._hyper_bridge)
|
||||
|
||||
@callback
|
||||
def _update_from_data(self):
|
||||
"""Nothing to update as buttons are stateless."""
|
@ -37,8 +37,6 @@ class AugustCamera(AugustEntityMixin, Camera):
|
||||
def __init__(self, data, device, session, timeout):
|
||||
"""Initialize a August security camera."""
|
||||
super().__init__(data, device)
|
||||
self._data = data
|
||||
self._device = device
|
||||
self._timeout = timeout
|
||||
self._session = session
|
||||
self._image_url = None
|
||||
|
@ -46,6 +46,7 @@ ACTIVITY_UPDATE_INTERVAL = timedelta(seconds=10)
|
||||
LOGIN_METHODS = ["phone", "email"]
|
||||
|
||||
PLATFORMS = [
|
||||
Platform.BUTTON,
|
||||
Platform.CAMERA,
|
||||
Platform.BINARY_SENSOR,
|
||||
Platform.LOCK,
|
||||
|
@ -36,6 +36,11 @@ class AugustEntityMixin(Entity):
|
||||
def _detail(self):
|
||||
return self._data.get_device_detail(self._device.device_id)
|
||||
|
||||
@property
|
||||
def _hyper_bridge(self):
|
||||
"""Check if the lock has a paired hyper bridge."""
|
||||
return bool(self._detail.bridge and self._detail.bridge.hyper_bridge)
|
||||
|
||||
@callback
|
||||
def _update_from_data_and_write_state(self):
|
||||
self._update_from_data()
|
||||
|
@ -39,18 +39,11 @@ class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
|
||||
def __init__(self, data, device):
|
||||
"""Initialize the lock."""
|
||||
super().__init__(data, device)
|
||||
self._data = data
|
||||
self._device = device
|
||||
self._lock_status = None
|
||||
self._attr_name = device.device_name
|
||||
self._attr_unique_id = f"{self._device_id:s}_lock"
|
||||
self._update_from_data()
|
||||
|
||||
@property
|
||||
def _hyper_bridge(self):
|
||||
"""Check if the lock has a paired hyper bridge."""
|
||||
return bool(self._detail.bridge and self._detail.bridge.hyper_bridge)
|
||||
|
||||
async def async_lock(self, **kwargs):
|
||||
"""Lock the device."""
|
||||
if self._data.activity_stream.pubnub.connected:
|
||||
|
@ -75,7 +75,16 @@ async def _mock_setup_august(
|
||||
return entry
|
||||
|
||||
|
||||
async def _create_august_with_devices( # noqa: C901
|
||||
async def _create_august_with_devices(
|
||||
hass, devices, api_call_side_effects=None, activities=None, pubnub=None
|
||||
):
|
||||
entry, api_instance = await _create_august_api_with_devices(
|
||||
hass, devices, api_call_side_effects, activities, pubnub
|
||||
)
|
||||
return entry
|
||||
|
||||
|
||||
async def _create_august_api_with_devices( # noqa: C901
|
||||
hass, devices, api_call_side_effects=None, activities=None, pubnub=None
|
||||
):
|
||||
if api_call_side_effects is None:
|
||||
@ -171,7 +180,7 @@ async def _create_august_with_devices( # noqa: C901
|
||||
# are any locks
|
||||
assert api_instance.async_status_async.mock_calls
|
||||
|
||||
return entry
|
||||
return entry, api_instance
|
||||
|
||||
|
||||
async def _mock_setup_august_with_api_side_effects(hass, api_call_side_effects, pubnub):
|
||||
|
27
tests/components/august/test_button.py
Normal file
27
tests/components/august/test_button.py
Normal file
@ -0,0 +1,27 @@
|
||||
"""The button tests for the august platform."""
|
||||
|
||||
from homeassistant.components.button import DOMAIN as BUTTON_DOMAIN
|
||||
from homeassistant.components.button.const import SERVICE_PRESS
|
||||
from homeassistant.const import ATTR_ENTITY_ID
|
||||
|
||||
from tests.components.august.mocks import (
|
||||
_create_august_api_with_devices,
|
||||
_mock_lock_from_fixture,
|
||||
)
|
||||
|
||||
|
||||
async def test_wake_lock(hass):
|
||||
"""Test creation of a lock and wake it."""
|
||||
lock_one = await _mock_lock_from_fixture(
|
||||
hass, "get_lock.online_with_doorsense.json"
|
||||
)
|
||||
_, api_instance = await _create_august_api_with_devices(hass, [lock_one])
|
||||
entity_id = "button.online_with_doorsense_name_wake"
|
||||
binary_sensor_online_with_doorsense_name = hass.states.get(entity_id)
|
||||
assert binary_sensor_online_with_doorsense_name is not None
|
||||
api_instance.async_status_async.reset_mock()
|
||||
assert await hass.services.async_call(
|
||||
BUTTON_DOMAIN, SERVICE_PRESS, {ATTR_ENTITY_ID: entity_id}, blocking=True
|
||||
)
|
||||
await hass.async_block_till_done()
|
||||
api_instance.async_status_async.assert_called_once()
|
Loading…
x
Reference in New Issue
Block a user