From a4b90c987990e8a3ce8bcce163ed1af7b5b2db9c Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sat, 27 Aug 2016 22:44:22 +0200 Subject: [PATCH] Use voluptuous for Raspberry Pi and local file camera (#2988) * Migrate to voluptuous * Update const.py * Migrate to voluptuous * Remove duplicate _LOGGER entry --- homeassistant/components/camera/local_file.py | 11 ++- homeassistant/components/camera/rpi_camera.py | 96 +++++++++++++------ homeassistant/const.py | 1 + 3 files changed, 75 insertions(+), 33 deletions(-) diff --git a/homeassistant/components/camera/local_file.py b/homeassistant/components/camera/local_file.py index f7df934d9de..65defb4557b 100644 --- a/homeassistant/components/camera/local_file.py +++ b/homeassistant/components/camera/local_file.py @@ -1,5 +1,9 @@ -"""Camera that loads a picture from a local file.""" +""" +Camera that loads a picture from a local file. +For more details about this platform, please refer to the documentation at +https://home-assistant.io/components/camera.local_file/ +""" import logging import os @@ -9,7 +13,10 @@ from homeassistant.const import CONF_NAME from homeassistant.components.camera import Camera, PLATFORM_SCHEMA from homeassistant.helpers import config_validation as cv +_LOGGER = logging.getLogger(__name__) + CONF_FILE_PATH = 'file_path' + DEFAULT_NAME = 'Local File' PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ @@ -17,8 +24,6 @@ PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string }) -_LOGGER = logging.getLogger(__name__) - def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Camera.""" diff --git a/homeassistant/components/camera/rpi_camera.py b/homeassistant/components/camera/rpi_camera.py index ee67d097286..22ab72ad8e7 100644 --- a/homeassistant/components/camera/rpi_camera.py +++ b/homeassistant/components/camera/rpi_camera.py @@ -9,41 +9,77 @@ import subprocess import logging import shutil -from homeassistant.components.camera import Camera +import voluptuous as vol + +from homeassistant.components.camera import (Camera, PLATFORM_SCHEMA) +from homeassistant.const import (CONF_NAME, CONF_FILE_PATH) +from homeassistant.helpers import config_validation as cv _LOGGER = logging.getLogger(__name__) +CONF_HORIZONTAL_FLIP = 'horizontal_flip' +CONF_IMAGE_HEIGHT = 'image_height' +CONF_IMAGE_QUALITY = 'image_quality' +CONF_IMAGE_ROTATION = 'image_rotation' +CONF_IMAGE_WIDTH = 'image_width' +CONF_TIMELAPSE = 'timelapse' +CONF_VERTICAL_FLIP = 'vertical_flip' + +DEFAULT_HORIZONTAL_FLIP = 0 +DEFAULT_IMAGE_HEIGHT = 480 +DEFAULT_IMAGE_QUALITIY = 7 +DEFAULT_IMAGE_ROTATION = 0 +DEFAULT_IMAGE_WIDTH = 640 +DEFAULT_NAME = 'Raspberry Pi Camera' +DEFAULT_TIMELAPSE = 1000 +DEFAULT_VERTICAL_FLIP = 0 + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Optional(CONF_FILE_PATH): cv.isfile, + vol.Optional(CONF_HORIZONTAL_FLIP, default=DEFAULT_HORIZONTAL_FLIP): + vol.All(vol.Coerce(int), vol.Range(min=0, max=1)), + vol.Optional(CONF_IMAGE_HEIGHT, default=DEFAULT_HORIZONTAL_FLIP): + vol.Coerce(int), + vol.Optional(CONF_IMAGE_QUALITY, default=DEFAULT_IMAGE_QUALITIY): + vol.All(vol.Coerce(int), vol.Range(min=0, max=100)), + vol.Optional(CONF_IMAGE_ROTATION, default=DEFAULT_IMAGE_ROTATION): + vol.All(vol.Coerce(int), vol.Range(min=0, max=359)), + vol.Optional(CONF_IMAGE_WIDTH, default=DEFAULT_IMAGE_WIDTH): + vol.Coerce(int), + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_TIMELAPSE, default=1000): vol.Coerce(int), + vol.Optional(CONF_VERTICAL_FLIP, default=DEFAULT_VERTICAL_FLIP): + vol.All(vol.Coerce(int), vol.Range(min=0, max=1)), +}) + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the Raspberry Camera.""" if shutil.which("raspistill") is None: - _LOGGER.error("Error: raspistill not found") + _LOGGER.error("'raspistill' was not found") return False setup_config = ( { - "name": config.get("name", "Raspberry Pi Camera"), - "image_width": int(config.get("image_width", "640")), - "image_height": int(config.get("image_height", "480")), - "image_quality": int(config.get("image_quality", "7")), - "image_rotation": int(config.get("image_rotation", "0")), - "timelapse": int(config.get("timelapse", "2000")), - "horizontal_flip": int(config.get("horizontal_flip", "0")), - "vertical_flip": int(config.get("vertical_flip", "0")), - "file_path": config.get("file_path", - os.path.join(os.path.dirname(__file__), - 'image.jpg')) + CONF_NAME: config.get(CONF_NAME), + CONF_IMAGE_WIDTH: config.get(CONF_IMAGE_WIDTH), + CONF_IMAGE_HEIGHT: config.get(CONF_IMAGE_HEIGHT), + CONF_IMAGE_QUALITY: config.get(CONF_IMAGE_QUALITY), + CONF_IMAGE_ROTATION: config.get(CONF_IMAGE_ROTATION), + CONF_TIMELAPSE: config.get(CONF_TIMELAPSE), + CONF_HORIZONTAL_FLIP: config.get(CONF_HORIZONTAL_FLIP), + CONF_VERTICAL_FLIP: config.get(CONF_VERTICAL_FLIP), + CONF_FILE_PATH: config.get(CONF_FILE_PATH, + os.path.join(os.path.dirname(__file__), + 'image.jpg')) } ) - # check filepath given is writable - if not os.access(setup_config["file_path"], os.W_OK): - _LOGGER.error("Error: file path is not writable") + if not os.access(setup_config[CONF_FILE_PATH], os.W_OK): + _LOGGER.error("File path is not writable") return False - add_devices([ - RaspberryCamera(setup_config) - ]) + add_devices([RaspberryCamera(setup_config)]) class RaspberryCamera(Camera): @@ -53,26 +89,26 @@ class RaspberryCamera(Camera): """Initialize Raspberry Pi camera component.""" super().__init__() - self._name = device_info["name"] + self._name = device_info[CONF_NAME] self._config = device_info - # kill if there's raspistill instance + # Kill if there's raspistill instance subprocess.Popen(['killall', 'raspistill'], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT) cmd_args = [ - 'raspistill', '--nopreview', '-o', str(device_info["file_path"]), - '-t', '0', '-w', str(device_info["image_width"]), - '-h', str(device_info["image_height"]), - '-tl', str(device_info["timelapse"]), - '-q', str(device_info["image_quality"]), - '-rot', str(device_info["image_rotation"]) + 'raspistill', '--nopreview', '-o', device_info[CONF_FILE_PATH], + '-t', '0', '-w', str(device_info[CONF_IMAGE_WIDTH]), + '-h', str(device_info[CONF_IMAGE_HEIGHT]), + '-tl', str(device_info[CONF_TIMELAPSE]), + '-q', str(device_info[CONF_IMAGE_QUALITY]), + '-rot', str(device_info[CONF_IMAGE_ROTATION]) ] - if device_info["horizontal_flip"]: + if device_info[CONF_HORIZONTAL_FLIP]: cmd_args.append("-hf") - if device_info["vertical_flip"]: + if device_info[CONF_VERTICAL_FLIP]: cmd_args.append("-vf") subprocess.Popen(cmd_args, @@ -81,7 +117,7 @@ class RaspberryCamera(Camera): def camera_image(self): """Return raspstill image response.""" - with open(self._config["file_path"], 'rb') as file: + with open(self._config[CONF_FILE_PATH], 'rb') as file: return file.read() @property diff --git a/homeassistant/const.py b/homeassistant/const.py index 76fc1226ca1..dc6f7f18345 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -37,6 +37,7 @@ CONF_ELEVATION = 'elevation' CONF_ENTITY_ID = 'entity_id' CONF_ENTITY_NAMESPACE = 'entity_namespace' CONF_EVENT = 'event' +CONF_FILE_PATH = 'file_path' CONF_FILENAME = 'filename' CONF_HOST = 'host' CONF_HOSTS = 'hosts'