Merge pull request #1290 from balloob/cleanup-camera

Cleanup camera
This commit is contained in:
Paulus Schoutsen 2016-02-16 23:59:10 -08:00
commit bd3f0c101d
4 changed files with 60 additions and 48 deletions

View File

@ -1,8 +1,6 @@
# pylint: disable=too-many-lines # pylint: disable=too-many-lines
""" """
homeassistant.components.camera Component to interface with cameras.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Component to interface with various cameras.
For more details about this component, please refer to the documentation at For more details about this component, please refer to the documentation at
https://home-assistant.io/components/camera/ https://home-assistant.io/components/camera/
@ -24,33 +22,17 @@ from homeassistant.const import (
DOMAIN = 'camera' DOMAIN = 'camera'
DEPENDENCIES = ['http'] DEPENDENCIES = ['http']
GROUP_NAME_ALL_CAMERAS = 'all_cameras'
SCAN_INTERVAL = 30 SCAN_INTERVAL = 30
ENTITY_ID_FORMAT = DOMAIN + '.{}' ENTITY_ID_FORMAT = DOMAIN + '.{}'
SWITCH_ACTION_RECORD = 'record'
SWITCH_ACTION_SNAPSHOT = 'snapshot'
SERVICE_CAMERA = 'camera_service'
DEFAULT_RECORDING_SECONDS = 30
# Maps discovered services to their platforms # Maps discovered services to their platforms
DISCOVERY_PLATFORMS = {} DISCOVERY_PLATFORMS = {}
FILE_DATETIME_FORMAT = '%Y-%m-%d_%H-%M-%S-%f'
DIR_DATETIME_FORMAT = '%Y-%m-%d_%H-%M-%S'
REC_DIR_PREFIX = 'recording-'
REC_IMG_PREFIX = 'recording_image-'
STATE_RECORDING = 'recording' STATE_RECORDING = 'recording'
STATE_STREAMING = 'streaming' STATE_STREAMING = 'streaming'
STATE_IDLE = 'idle' STATE_IDLE = 'idle'
CAMERA_PROXY_URL = '/api/camera_proxy_stream/{0}' ENTITY_IMAGE_URL = '/api/camera_proxy/{0}'
CAMERA_STILL_URL = '/api/camera_proxy/{0}'
ENTITY_IMAGE_URL = '/api/camera_proxy/{0}?time={1}'
MULTIPART_BOUNDARY = '--jpegboundary' MULTIPART_BOUNDARY = '--jpegboundary'
MJPEG_START_HEADER = 'Content-type: {0}\r\n\r\n' MJPEG_START_HEADER = 'Content-type: {0}\r\n\r\n'
@ -58,8 +40,7 @@ MJPEG_START_HEADER = 'Content-type: {0}\r\n\r\n'
# pylint: disable=too-many-branches # pylint: disable=too-many-branches
def setup(hass, config): def setup(hass, config):
""" Track states and offer events for cameras. """ """Initialize camera component."""
component = EntityComponent( component = EntityComponent(
logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL, logging.getLogger(__name__), DOMAIN, hass, SCAN_INTERVAL,
DISCOVERY_PLATFORMS) DISCOVERY_PLATFORMS)
@ -78,7 +59,7 @@ def setup(hass, config):
# pylint: disable=unused-argument # pylint: disable=unused-argument
def _proxy_camera_image(handler, path_match, data): def _proxy_camera_image(handler, path_match, data):
""" Proxies the camera image via the HA server. """ """Serve the camera image via the HA server."""
entity_id = path_match.group(ATTR_ENTITY_ID) entity_id = path_match.group(ATTR_ENTITY_ID)
camera = component.entities.get(entity_id) camera = component.entities.get(entity_id)
@ -104,7 +85,8 @@ def setup(hass, config):
# pylint: disable=unused-argument # pylint: disable=unused-argument
def _proxy_camera_mjpeg_stream(handler, path_match, data): def _proxy_camera_mjpeg_stream(handler, path_match, data):
""" """
Proxies the camera image as an mjpeg stream via the HA server. Proxy the camera image as an mjpeg stream via the HA server.
This function takes still images from the IP camera and turns them This function takes still images from the IP camera and turns them
into an MJPEG stream. This means that HA can return a live video into an MJPEG stream. This means that HA can return a live video
stream even with only a still image URL available. stream even with only a still image URL available.
@ -136,35 +118,41 @@ def setup(hass, config):
class Camera(Entity): class Camera(Entity):
""" The base class for camera components. """ """The base class for camera entities."""
def __init__(self): def __init__(self):
"""Initialize a camera."""
self.is_streaming = False self.is_streaming = False
@property
def should_poll(self):
"""No need to poll cameras."""
return False
@property @property
# pylint: disable=no-self-use # pylint: disable=no-self-use
def is_recording(self): def is_recording(self):
""" Returns true if the device is recording. """ """Return true if the device is recording."""
return False return False
@property @property
# pylint: disable=no-self-use # pylint: disable=no-self-use
def brand(self): def brand(self):
""" Should return a string of the camera brand. """ """Camera brand."""
return None return None
@property @property
# pylint: disable=no-self-use # pylint: disable=no-self-use
def model(self): def model(self):
""" Returns string of camera model. """ """Camera model."""
return None return None
def camera_image(self): def camera_image(self):
""" Return bytes of camera image. """ """Return bytes of camera image."""
raise NotImplementedError() raise NotImplementedError()
def mjpeg_stream(self, handler): def mjpeg_stream(self, handler):
""" Generate an HTTP MJPEG stream from camera images. """ """Generate an HTTP MJPEG stream from camera images."""
handler.request.sendall(bytes('HTTP/1.1 200 OK\r\n', 'utf-8')) handler.request.sendall(bytes('HTTP/1.1 200 OK\r\n', 'utf-8'))
handler.request.sendall(bytes( handler.request.sendall(bytes(
'Content-type: multipart/x-mixed-replace; \ 'Content-type: multipart/x-mixed-replace; \
@ -193,7 +181,7 @@ class Camera(Entity):
@property @property
def state(self): def state(self):
""" Returns the state of the entity. """ """Camera state."""
if self.is_recording: if self.is_recording:
return STATE_RECORDING return STATE_RECORDING
elif self.is_streaming: elif self.is_streaming:
@ -203,10 +191,9 @@ class Camera(Entity):
@property @property
def state_attributes(self): def state_attributes(self):
""" Returns optional state attributes. """ """Camera state attributes."""
attr = { attr = {
ATTR_ENTITY_PICTURE: ENTITY_IMAGE_URL.format( ATTR_ENTITY_PICTURE: ENTITY_IMAGE_URL.format(self.entity_id),
self.entity_id, time.time()),
} }
if self.model: if self.model:

View File

@ -1,2 +1,2 @@
""" DO NOT MODIFY. Auto-generated by build_frontend script """ """ DO NOT MODIFY. Auto-generated by build_frontend script """
VERSION = "c11382dc4f1efd426f94d77cf498b954" VERSION = "4ae370eaaad6bc779d08713b79ce3cba"

File diff suppressed because one or more lines are too long

@ -1 +1 @@
Subproject commit 75cc118cb121f10cd2e4dd98c9b99ce1219c485a Subproject commit 4cdefac2fe6f016fa09d872c8cb062ba01442b08