hass-core/homeassistant/components/doorbird/camera.py
Tsvi Mostovicz 80136f3591 Change datetime.now() to dt_util.now() (#26582)
* Change datetime.now() to dt_util.now() in cases where the functionality should stay the same

These changes should not affect the functionality, rather cleanup our codebase.

In general we would like integrations to not to use datetime.now() unless there's a very good
reason for it, rather use our own dt_util.now() which makes the code aware of our current time
zone.

* Use datetime.utcnow() for season sensor to get offset-naive utc time

* Revert "Use datetime.utcnow() for season sensor to get offset-naive utc time"

This reverts commit 5f36463d9c7d52f8e11ffcec7e57dfbc7b21bdd1.

* BOM sensor last_updated should be UTC as well

* Run black

* Remove unused last_partition_update variable
2019-09-19 08:39:09 +02:00

99 lines
3.3 KiB
Python

"""Support for viewing the camera feed from a DoorBird video doorbell."""
import asyncio
import datetime
import logging
import aiohttp
import async_timeout
from homeassistant.components.camera import Camera, SUPPORT_STREAM
from homeassistant.helpers.aiohttp_client import async_get_clientsession
import homeassistant.util.dt as dt_util
from . import DOMAIN as DOORBIRD_DOMAIN
_CAMERA_LAST_VISITOR = "{} Last Ring"
_CAMERA_LAST_MOTION = "{} Last Motion"
_CAMERA_LIVE = "{} Live"
_LAST_VISITOR_INTERVAL = datetime.timedelta(minutes=1)
_LAST_MOTION_INTERVAL = datetime.timedelta(minutes=1)
_LIVE_INTERVAL = datetime.timedelta(seconds=1)
_LOGGER = logging.getLogger(__name__)
_TIMEOUT = 10 # seconds
async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
"""Set up the DoorBird camera platform."""
for doorstation in hass.data[DOORBIRD_DOMAIN]:
device = doorstation.device
async_add_entities(
[
DoorBirdCamera(
device.live_image_url,
_CAMERA_LIVE.format(doorstation.name),
_LIVE_INTERVAL,
device.rtsp_live_video_url,
),
DoorBirdCamera(
device.history_image_url(1, "doorbell"),
_CAMERA_LAST_VISITOR.format(doorstation.name),
_LAST_VISITOR_INTERVAL,
),
DoorBirdCamera(
device.history_image_url(1, "motionsensor"),
_CAMERA_LAST_MOTION.format(doorstation.name),
_LAST_MOTION_INTERVAL,
),
]
)
class DoorBirdCamera(Camera):
"""The camera on a DoorBird device."""
def __init__(self, url, name, interval=None, stream_url=None):
"""Initialize the camera on a DoorBird device."""
self._url = url
self._stream_url = stream_url
self._name = name
self._last_image = None
self._supported_features = SUPPORT_STREAM if self._stream_url else 0
self._interval = interval or datetime.timedelta
self._last_update = datetime.datetime.min
super().__init__()
async def stream_source(self):
"""Return the stream source."""
return self._stream_url
@property
def supported_features(self):
"""Return supported features."""
return self._supported_features
@property
def name(self):
"""Get the name of the camera."""
return self._name
async def async_camera_image(self):
"""Pull a still image from the camera."""
now = dt_util.utcnow()
if self._last_image and now - self._last_update < self._interval:
return self._last_image
try:
websession = async_get_clientsession(self.hass)
with async_timeout.timeout(_TIMEOUT):
response = await websession.get(self._url)
self._last_image = await response.read()
self._last_update = now
return self._last_image
except asyncio.TimeoutError:
_LOGGER.error("Camera image timed out")
return self._last_image
except aiohttp.ClientError as error:
_LOGGER.error("Error getting camera image: %s", error)
return self._last_image