2020-02-27 02:48:44 +00:00
|
|
|
"""Support for August doorbell camera."""
|
2024-03-08 13:51:32 +00:00
|
|
|
|
2021-08-11 00:33:06 +00:00
|
|
|
from __future__ import annotations
|
2018-02-18 08:24:51 +00:00
|
|
|
|
2024-03-10 08:11:10 +00:00
|
|
|
import logging
|
|
|
|
|
2024-01-18 22:13:08 +00:00
|
|
|
from aiohttp import ClientSession
|
2021-03-22 05:35:12 +00:00
|
|
|
from yalexs.activity import ActivityType
|
2024-06-18 23:52:41 +00:00
|
|
|
from yalexs.doorbell import Doorbell
|
2021-03-22 05:35:12 +00:00
|
|
|
from yalexs.util import update_doorbell_image_from_activity
|
2018-02-18 08:24:51 +00:00
|
|
|
|
|
|
|
from homeassistant.components.camera import Camera
|
2022-01-03 12:22:41 +00:00
|
|
|
from homeassistant.core import HomeAssistant, callback
|
2020-03-09 20:54:05 +00:00
|
|
|
from homeassistant.helpers import aiohttp_client
|
2022-01-03 12:22:41 +00:00
|
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
2018-02-18 08:24:51 +00:00
|
|
|
|
2024-05-02 12:39:02 +00:00
|
|
|
from . import AugustConfigEntry, AugustData
|
|
|
|
from .const import DEFAULT_NAME, DEFAULT_TIMEOUT
|
2020-02-28 03:44:23 +00:00
|
|
|
from .entity import AugustEntityMixin
|
2018-02-18 08:24:51 +00:00
|
|
|
|
2024-03-10 08:11:10 +00:00
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
2018-02-18 08:24:51 +00:00
|
|
|
|
2022-01-03 12:22:41 +00:00
|
|
|
async def async_setup_entry(
|
|
|
|
hass: HomeAssistant,
|
2024-05-02 12:39:02 +00:00
|
|
|
config_entry: AugustConfigEntry,
|
2022-01-03 12:22:41 +00:00
|
|
|
async_add_entities: AddEntitiesCallback,
|
|
|
|
) -> None:
|
2018-02-18 08:24:51 +00:00
|
|
|
"""Set up August cameras."""
|
2024-05-02 12:39:02 +00:00
|
|
|
data = config_entry.runtime_data
|
2023-01-23 09:14:29 +00:00
|
|
|
# Create an aiohttp session instead of using the default one since the
|
|
|
|
# default one is likely to trigger august's WAF if another integration
|
|
|
|
# is also using Cloudflare
|
|
|
|
session = aiohttp_client.async_create_clientsession(hass)
|
2021-04-25 09:32:34 +00:00
|
|
|
async_add_entities(
|
2022-03-15 18:05:56 +00:00
|
|
|
AugustCamera(data, doorbell, session, DEFAULT_TIMEOUT)
|
|
|
|
for doorbell in data.doorbells
|
2021-04-25 09:32:34 +00:00
|
|
|
)
|
2018-02-18 08:24:51 +00:00
|
|
|
|
|
|
|
|
2020-02-28 03:44:23 +00:00
|
|
|
class AugustCamera(AugustEntityMixin, Camera):
|
2023-08-14 14:58:57 +00:00
|
|
|
"""An implementation of an August security camera."""
|
|
|
|
|
|
|
|
_attr_translation_key = "camera"
|
2024-06-18 20:43:16 +00:00
|
|
|
_attr_motion_detection_enabled = True
|
|
|
|
_attr_brand = DEFAULT_NAME
|
2024-06-18 22:35:55 +00:00
|
|
|
_image_url: str | None = None
|
|
|
|
_image_content: bytes | None = None
|
2018-02-18 08:24:51 +00:00
|
|
|
|
2024-01-18 22:13:08 +00:00
|
|
|
def __init__(
|
|
|
|
self, data: AugustData, device: Doorbell, session: ClientSession, timeout: int
|
|
|
|
) -> None:
|
2023-08-14 14:58:57 +00:00
|
|
|
"""Initialize an August security camera."""
|
2024-06-19 01:43:06 +00:00
|
|
|
super().__init__(data, device, "camera")
|
2018-02-18 08:24:51 +00:00
|
|
|
self._timeout = timeout
|
2021-04-25 09:32:34 +00:00
|
|
|
self._session = session
|
2024-06-19 14:21:04 +00:00
|
|
|
self._attr_model = self._detail.model
|
2018-02-18 08:24:51 +00:00
|
|
|
|
|
|
|
@property
|
2022-08-18 13:56:52 +00:00
|
|
|
def is_recording(self) -> bool:
|
2018-02-18 08:24:51 +00:00
|
|
|
"""Return true if the device is recording."""
|
2020-02-28 03:44:23 +00:00
|
|
|
return self._device.has_subscription
|
2018-02-18 08:24:51 +00:00
|
|
|
|
2024-03-10 08:11:10 +00:00
|
|
|
async def _async_update(self):
|
|
|
|
"""Update device."""
|
|
|
|
_LOGGER.debug("async_update called %s", self._detail.device_name)
|
|
|
|
await self._data.refresh_camera_by_id(self._device_id)
|
|
|
|
self._update_from_data()
|
|
|
|
|
2020-02-28 03:44:23 +00:00
|
|
|
@callback
|
2024-01-18 23:14:49 +00:00
|
|
|
def _update_from_data(self) -> None:
|
2020-02-28 03:44:23 +00:00
|
|
|
"""Get the latest state of the sensor."""
|
2024-06-19 14:21:04 +00:00
|
|
|
if doorbell_activity := self._get_latest(
|
|
|
|
{ActivityType.DOORBELL_MOTION, ActivityType.DOORBELL_IMAGE_CAPTURE}
|
|
|
|
):
|
2020-02-28 03:44:23 +00:00
|
|
|
update_doorbell_image_from_activity(self._detail, doorbell_activity)
|
2020-02-26 07:43:41 +00:00
|
|
|
|
2021-08-11 00:33:06 +00:00
|
|
|
async def async_camera_image(
|
|
|
|
self, width: int | None = None, height: int | None = None
|
|
|
|
) -> bytes | None:
|
2020-02-28 03:44:23 +00:00
|
|
|
"""Return bytes of camera image."""
|
|
|
|
self._update_from_data()
|
2020-02-25 18:18:15 +00:00
|
|
|
|
2020-02-28 03:44:23 +00:00
|
|
|
if self._image_url is not self._detail.image_url:
|
2024-06-18 23:52:41 +00:00
|
|
|
self._image_content = await self._data.async_get_doorbell_image(
|
|
|
|
self._device_id, self._session, timeout=self._timeout
|
2020-02-21 06:39:07 +00:00
|
|
|
)
|
2024-06-18 23:52:41 +00:00
|
|
|
self._image_url = self._detail.image_url
|
2024-03-10 08:11:10 +00:00
|
|
|
|
2018-02-18 08:24:51 +00:00
|
|
|
return self._image_content
|