Small cleanups for august (#49493)

This commit is contained in:
J. Nick Koston 2021-04-24 23:32:34 -10:00 committed by GitHub
parent 153d6e891e
commit e2837f08e8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 123 additions and 26 deletions

View File

@ -2,7 +2,7 @@
from datetime import datetime, timedelta
import logging
from yalexs.activity import ACTION_DOORBELL_CALL_MISSED, ActivityType
from yalexs.activity import ACTION_DOORBELL_CALL_MISSED, SOURCE_PUBNUB, ActivityType
from yalexs.lock import LockDoorStatus
from yalexs.util import update_lock_detail_from_activity
@ -97,7 +97,7 @@ SENSOR_TYPES_DOORBELL = {
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the August binary sensors."""
data = hass.data[DOMAIN][config_entry.entry_id][DATA_AUGUST]
devices = []
entities = []
for door in data.locks:
detail = data.get_device_detail(door.device_id)
@ -109,7 +109,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
continue
_LOGGER.debug("Adding sensor class door for %s", door.device_name)
devices.append(AugustDoorBinarySensor(data, "door_open", door))
entities.append(AugustDoorBinarySensor(data, "door_open", door))
for doorbell in data.doorbells:
for sensor_type in SENSOR_TYPES_DOORBELL:
@ -118,9 +118,9 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
SENSOR_TYPES_DOORBELL[sensor_type][SENSOR_DEVICE_CLASS],
doorbell.device_name,
)
devices.append(AugustDoorbellBinarySensor(data, sensor_type, doorbell))
entities.append(AugustDoorbellBinarySensor(data, sensor_type, doorbell))
async_add_entities(devices, True)
async_add_entities(entities)
class AugustDoorBinarySensor(AugustEntityMixin, BinarySensorEntity):
@ -163,6 +163,9 @@ class AugustDoorBinarySensor(AugustEntityMixin, BinarySensorEntity):
if door_activity is not None:
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 door_activity.source == SOURCE_PUBNUB:
self._detail.set_online(True)
bridge_activity = self._data.activity_stream.get_latest_device_activity(
self._device_id, {ActivityType.BRIDGE_OPERATION}

View File

@ -14,23 +14,25 @@ from .entity import AugustEntityMixin
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up August cameras."""
data = hass.data[DOMAIN][config_entry.entry_id][DATA_AUGUST]
devices = []
for doorbell in data.doorbells:
devices.append(AugustCamera(data, doorbell, DEFAULT_TIMEOUT))
async_add_entities(devices, True)
session = aiohttp_client.async_get_clientsession(hass)
async_add_entities(
[
AugustCamera(data, doorbell, session, DEFAULT_TIMEOUT)
for doorbell in data.doorbells
]
)
class AugustCamera(AugustEntityMixin, Camera):
"""An implementation of a August security camera."""
def __init__(self, data, device, timeout):
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
self._image_content = None
@ -76,7 +78,7 @@ class AugustCamera(AugustEntityMixin, Camera):
if self._image_url is not self._detail.image_url:
self._image_url = self._detail.image_url
self._image_content = await self._detail.async_get_doorbell_image(
aiohttp_client.async_get_clientsession(self.hass), timeout=self._timeout
self._session, timeout=self._timeout
)
return self._image_content

View File

@ -1,7 +1,7 @@
"""Support for August lock."""
import logging
from yalexs.activity import ActivityType
from yalexs.activity import SOURCE_PUBNUB, ActivityType
from yalexs.lock import LockStatus
from yalexs.util import update_lock_detail_from_activity
@ -19,13 +19,7 @@ _LOGGER = logging.getLogger(__name__)
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up August locks."""
data = hass.data[DOMAIN][config_entry.entry_id][DATA_AUGUST]
devices = []
for lock in data.locks:
_LOGGER.debug("Adding lock for %s", lock.device_name)
devices.append(AugustLock(data, lock))
async_add_entities(devices, True)
async_add_entities([AugustLock(data, lock) for lock in data.locks])
class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
@ -80,6 +74,9 @@ class AugustLock(AugustEntityMixin, RestoreEntity, LockEntity):
if lock_activity is not None:
self._changed_by = lock_activity.operated_by
update_lock_detail_from_activity(self._detail, lock_activity)
# If the source is pubnub the lock must be online since its a live update
if lock_activity.source == SOURCE_PUBNUB:
self._detail.set_online(True)
bridge_activity = self._data.activity_stream.get_latest_device_activity(
self._device_id, {ActivityType.BRIDGE_OPERATION}

View File

@ -45,7 +45,7 @@ SENSOR_TYPES_BATTERY = {
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the August sensors."""
data = hass.data[DOMAIN][config_entry.entry_id][DATA_AUGUST]
devices = []
entities = []
migrate_unique_id_devices = []
operation_sensors = []
batteries = {
@ -72,7 +72,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
"Adding battery sensor for %s",
device.device_name,
)
devices.append(AugustBatterySensor(data, "device_battery", device, device))
entities.append(AugustBatterySensor(data, "device_battery", device, device))
for device in batteries["linked_keypad_battery"]:
detail = data.get_device_detail(device.device_id)
@ -90,15 +90,15 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
keypad_battery_sensor = AugustBatterySensor(
data, "linked_keypad_battery", detail.keypad, device
)
devices.append(keypad_battery_sensor)
entities.append(keypad_battery_sensor)
migrate_unique_id_devices.append(keypad_battery_sensor)
for device in operation_sensors:
devices.append(AugustOperatorSensor(data, device))
entities.append(AugustOperatorSensor(data, device))
await _async_migrate_old_unique_ids(hass, migrate_unique_id_devices)
async_add_entities(devices, True)
async_add_entities(entities)
async def _async_migrate_old_unique_ids(hass, devices):

View File

@ -21,6 +21,7 @@ from tests.components.august.mocks import (
_create_august_with_devices,
_mock_activities_from_fixture,
_mock_doorbell_from_fixture,
_mock_doorsense_enabled_august_lock_detail,
_mock_lock_from_fixture,
)
@ -251,3 +252,97 @@ async def test_doorbell_device_registry(hass):
assert reg_device.name == "tmt100 Name"
assert reg_device.manufacturer == "August Home Inc."
assert reg_device.sw_version == "3.1.0-HYDRC75+201909251139"
async def test_door_sense_update_via_pubnub(hass):
"""Test creation of a lock with doorsense and bridge."""
lock_one = await _mock_doorsense_enabled_august_lock_detail(hass)
assert lock_one.pubsub_channel == "pubsub"
pubnub = AugustPubNub()
activities = await _mock_activities_from_fixture(hass, "get_activity.lock.json")
config_entry = await _create_august_with_devices(
hass, [lock_one], activities=activities, pubnub=pubnub
)
binary_sensor_online_with_doorsense_name = hass.states.get(
"binary_sensor.online_with_doorsense_name_open"
)
assert binary_sensor_online_with_doorsense_name.state == STATE_ON
pubnub.message(
pubnub,
Mock(
channel=lock_one.pubsub_channel,
timetoken=dt_util.utcnow().timestamp() * 10000000,
message={"status": "kAugLockState_Unlocking", "doorState": "closed"},
),
)
await hass.async_block_till_done()
binary_sensor_online_with_doorsense_name = hass.states.get(
"binary_sensor.online_with_doorsense_name_open"
)
assert binary_sensor_online_with_doorsense_name.state == STATE_OFF
pubnub.message(
pubnub,
Mock(
channel=lock_one.pubsub_channel,
timetoken=dt_util.utcnow().timestamp() * 10000000,
message={"status": "kAugLockState_Locking", "doorState": "open"},
),
)
await hass.async_block_till_done()
binary_sensor_online_with_doorsense_name = hass.states.get(
"binary_sensor.online_with_doorsense_name_open"
)
assert binary_sensor_online_with_doorsense_name.state == STATE_ON
async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(seconds=30))
await hass.async_block_till_done()
binary_sensor_online_with_doorsense_name = hass.states.get(
"binary_sensor.online_with_doorsense_name_open"
)
assert binary_sensor_online_with_doorsense_name.state == STATE_ON
pubnub.connected = True
async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(seconds=30))
await hass.async_block_till_done()
binary_sensor_online_with_doorsense_name = hass.states.get(
"binary_sensor.online_with_doorsense_name_open"
)
assert binary_sensor_online_with_doorsense_name.state == STATE_ON
# Ensure pubnub status is always preserved
async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(hours=2))
await hass.async_block_till_done()
binary_sensor_online_with_doorsense_name = hass.states.get(
"binary_sensor.online_with_doorsense_name_open"
)
assert binary_sensor_online_with_doorsense_name.state == STATE_ON
pubnub.message(
pubnub,
Mock(
channel=lock_one.pubsub_channel,
timetoken=dt_util.utcnow().timestamp() * 10000000,
message={"status": "kAugLockState_Unlocking", "doorState": "open"},
),
)
await hass.async_block_till_done()
binary_sensor_online_with_doorsense_name = hass.states.get(
"binary_sensor.online_with_doorsense_name_open"
)
assert binary_sensor_online_with_doorsense_name.state == STATE_ON
async_fire_time_changed(hass, dt_util.utcnow() + datetime.timedelta(hours=4))
await hass.async_block_till_done()
binary_sensor_online_with_doorsense_name = hass.states.get(
"binary_sensor.online_with_doorsense_name_open"
)
assert binary_sensor_online_with_doorsense_name.state == STATE_ON
await hass.config_entries.async_unload(config_entry.entry_id)
await hass.async_block_till_done()