From 5f508b6afa31d56df20d60b30ac2cc359e3e7f43 Mon Sep 17 00:00:00 2001 From: Fabian Affolter Date: Sun, 21 Aug 2016 01:28:45 +0200 Subject: [PATCH] Use voluptuous for REST platforms (#2887) * Initial step to migrate to voluptuous * Migrate to voluptuous * Add schema for sensor_classes --- .../components/binary_sensor/__init__.py | 4 ++ .../components/binary_sensor/rest.py | 46 +++++++------ homeassistant/components/notify/rest.py | 65 +++++++++++-------- homeassistant/components/sensor/rest.py | 41 ++++++++---- homeassistant/components/switch/rest.py | 40 +++++++----- homeassistant/const.py | 2 + 6 files changed, 122 insertions(+), 76 deletions(-) diff --git a/homeassistant/components/binary_sensor/__init__.py b/homeassistant/components/binary_sensor/__init__.py index 18cb8ea0cb2..2f751683265 100644 --- a/homeassistant/components/binary_sensor/__init__.py +++ b/homeassistant/components/binary_sensor/__init__.py @@ -6,6 +6,8 @@ https://home-assistant.io/components/binary_sensor/ """ import logging +import voluptuous as vol + from homeassistant.helpers.entity_component import EntityComponent from homeassistant.helpers.entity import Entity from homeassistant.const import (STATE_ON, STATE_OFF) @@ -33,6 +35,8 @@ SENSOR_CLASSES = [ 'vibration', # On means vibration detected, Off means no vibration ] +SENSOR_CLASSES_SCHEMA = vol.All(vol.Lower, vol.In(SENSOR_CLASSES)) + def setup(hass, config): """Track states and offer events for binary sensors.""" diff --git a/homeassistant/components/binary_sensor/rest.py b/homeassistant/components/binary_sensor/rest.py index d9a6f1d8947..4a6e48ca5a3 100644 --- a/homeassistant/components/binary_sensor/rest.py +++ b/homeassistant/components/binary_sensor/rest.py @@ -6,30 +6,42 @@ https://home-assistant.io/components/binary_sensor.rest/ """ import logging -from homeassistant.components.binary_sensor import (BinarySensorDevice, - SENSOR_CLASSES) +import voluptuous as vol + +from homeassistant.components.binary_sensor import ( + BinarySensorDevice, SENSOR_CLASSES_SCHEMA, PLATFORM_SCHEMA) from homeassistant.components.sensor.rest import RestData -from homeassistant.const import CONF_VALUE_TEMPLATE +from homeassistant.const import ( + CONF_PAYLOAD, CONF_NAME, CONF_VALUE_TEMPLATE, CONF_METHOD, CONF_RESOURCE, + CONF_SENSOR_CLASS) from homeassistant.helpers import template +import homeassistant.helpers.config_validation as cv + +DEFAULT_METHOD = 'GET' +DEFAULT_NAME = 'REST Binary Sensor' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(['POST', 'GET']), + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PAYLOAD): cv.string, + vol.Optional(CONF_SENSOR_CLASS): SENSOR_CLASSES_SCHEMA, + vol.Optional(CONF_VALUE_TEMPLATE): cv.template, +}) _LOGGER = logging.getLogger(__name__) -DEFAULT_NAME = 'REST Binary Sensor' -DEFAULT_METHOD = 'GET' - # pylint: disable=unused-variable def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the REST binary sensor.""" - resource = config.get('resource', None) - method = config.get('method', DEFAULT_METHOD) - payload = config.get('payload', None) + name = config.get(CONF_NAME) + resource = config.get(CONF_RESOURCE) + method = config.get(CONF_METHOD) + payload = config.get(CONF_PAYLOAD) verify_ssl = config.get('verify_ssl', True) - - sensor_class = config.get('sensor_class') - if sensor_class not in SENSOR_CLASSES: - _LOGGER.warning('Unknown sensor class: %s', sensor_class) - sensor_class = None + sensor_class = config.get(CONF_SENSOR_CLASS) + value_template = config.get(CONF_VALUE_TEMPLATE) rest = RestData(method, resource, payload, verify_ssl) rest.update() @@ -39,11 +51,7 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return False add_devices([RestBinarySensor( - hass, - rest, - config.get('name', DEFAULT_NAME), - sensor_class, - config.get(CONF_VALUE_TEMPLATE))]) + hass, rest, name, sensor_class, value_template)]) # pylint: disable=too-many-arguments diff --git a/homeassistant/components/notify/rest.py b/homeassistant/components/notify/rest.py index 6c913f4f639..5cc556a1957 100644 --- a/homeassistant/components/notify/rest.py +++ b/homeassistant/components/notify/rest.py @@ -1,5 +1,5 @@ """ -REST platform for notify component. +RESTful platform for notify component. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/notify.rest/ @@ -7,45 +7,56 @@ https://home-assistant.io/components/notify.rest/ import logging import requests +import voluptuous as vol from homeassistant.components.notify import ( - ATTR_TARGET, ATTR_TITLE, DOMAIN, BaseNotificationService) -from homeassistant.helpers import validate_config + ATTR_TARGET, ATTR_TITLE, BaseNotificationService, PLATFORM_SCHEMA) +from homeassistant.const import (CONF_RESOURCE, CONF_METHOD, CONF_NAME) +import homeassistant.helpers.config_validation as cv + +CONF_MESSAGE_PARAMETER_NAME = 'message_param_name' +CONF_TARGET_PARAMETER_NAME = 'target_param_name' +CONF_TITLE_PARAMETER_NAME = 'title_param_name' +DEFAULT_MESSAGE_PARAM_NAME = 'message' +DEFAULT_METHOD = 'GET' +DEFAULT_TARGET_PARAM_NAME = None +DEFAULT_TITLE_PARAM_NAME = None + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_MESSAGE_PARAMETER_NAME, + default=DEFAULT_MESSAGE_PARAM_NAME): cv.string, + vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): + vol.In(['POST', 'GET', 'POST_JSON']), + vol.Optional(CONF_NAME): cv.string, + vol.Optional(CONF_TARGET_PARAMETER_NAME, + default=DEFAULT_TARGET_PARAM_NAME): cv.string, + vol.Optional(CONF_TITLE_PARAMETER_NAME, + default=DEFAULT_TITLE_PARAM_NAME): cv.string, +}) _LOGGER = logging.getLogger(__name__) -DEFAULT_METHOD = 'GET' -DEFAULT_MESSAGE_PARAM_NAME = 'message' -DEFAULT_TITLE_PARAM_NAME = None -DEFAULT_TARGET_PARAM_NAME = None - def get_service(hass, config): - """Get the REST notification service.""" - if not validate_config({DOMAIN: config}, - {DOMAIN: ['resource', ]}, - _LOGGER): - return None + """Get the RESTful notification service.""" + resource = config.get(CONF_RESOURCE) + method = config.get(CONF_METHOD) + message_param_name = config.get(CONF_MESSAGE_PARAMETER_NAME) + title_param_name = config.get(CONF_TITLE_PARAMETER_NAME) + target_param_name = config.get(CONF_TARGET_PARAMETER_NAME) - method = config.get('method', DEFAULT_METHOD) - message_param_name = config.get('message_param_name', - DEFAULT_MESSAGE_PARAM_NAME) - title_param_name = config.get('title_param_name', - DEFAULT_TITLE_PARAM_NAME) - target_param_name = config.get('target_param_name', - DEFAULT_TARGET_PARAM_NAME) - - return RestNotificationService(config['resource'], method, - message_param_name, title_param_name, - target_param_name) + return RestNotificationService( + resource, method, message_param_name, title_param_name, + target_param_name) # pylint: disable=too-few-public-methods, too-many-arguments class RestNotificationService(BaseNotificationService): - """Implement the notification service for REST.""" + """Implementation of a notification service for REST.""" - def __init__(self, resource, method, message_param_name, - title_param_name, target_param_name): + def __init__(self, resource, method, message_param_name, title_param_name, + target_param_name): """Initialize the service.""" self._resource = resource self._method = method.upper() diff --git a/homeassistant/components/sensor/rest.py b/homeassistant/components/sensor/rest.py index 3f594c07234..022477d77a9 100644 --- a/homeassistant/components/sensor/rest.py +++ b/homeassistant/components/sensor/rest.py @@ -1,41 +1,56 @@ """ -Support for REST API sensors.. +Support for REST API sensors. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.rest/ """ import logging +import voluptuous as vol import requests -from homeassistant.const import CONF_VALUE_TEMPLATE, STATE_UNKNOWN +from homeassistant.components.sensor import PLATFORM_SCHEMA +from homeassistant.const import ( + CONF_PAYLOAD, CONF_NAME, CONF_VALUE_TEMPLATE, CONF_METHOD, CONF_RESOURCE, + CONF_UNIT_OF_MEASUREMENT, STATE_UNKNOWN) from homeassistant.helpers.entity import Entity from homeassistant.helpers import template +import homeassistant.helpers.config_validation as cv + +DEFAULT_METHOD = 'GET' +DEFAULT_NAME = 'REST Sensor' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_METHOD, default=DEFAULT_METHOD): vol.In(['POST', 'GET']), + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PAYLOAD): cv.string, + vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, + vol.Optional(CONF_VALUE_TEMPLATE): cv.template, +}) _LOGGER = logging.getLogger(__name__) -DEFAULT_NAME = 'REST Sensor' -DEFAULT_METHOD = 'GET' - # pylint: disable=unused-variable def setup_platform(hass, config, add_devices, discovery_info=None): - """Setup the REST sensor.""" - resource = config.get('resource', None) - method = config.get('method', DEFAULT_METHOD) - payload = config.get('payload', None) + """Setup the RESTful sensor.""" + name = config.get(CONF_NAME) + resource = config.get(CONF_RESOURCE) + method = config.get(CONF_METHOD) + payload = config.get(CONF_PAYLOAD) verify_ssl = config.get('verify_ssl', True) + unit = config.get(CONF_UNIT_OF_MEASUREMENT) + value_template = config.get(CONF_VALUE_TEMPLATE) rest = RestData(method, resource, payload, verify_ssl) rest.update() if rest.data is None: - _LOGGER.error('Unable to fetch Rest data') + _LOGGER.error('Unable to fetch REST data') return False - add_devices([RestSensor( - hass, rest, config.get('name', DEFAULT_NAME), - config.get('unit_of_measurement'), config.get(CONF_VALUE_TEMPLATE))]) + add_devices([RestSensor(hass, rest, name, unit, value_template)]) # pylint: disable=too-many-arguments diff --git a/homeassistant/components/switch/rest.py b/homeassistant/components/switch/rest.py index d4c8ebe026d..ee29dd13adb 100644 --- a/homeassistant/components/switch/rest.py +++ b/homeassistant/components/switch/rest.py @@ -7,24 +7,35 @@ https://home-assistant.io/components/switch.rest/ import logging import requests +import voluptuous as vol -from homeassistant.components.switch import SwitchDevice +from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA) +from homeassistant.const import (CONF_NAME, CONF_RESOURCE) +import homeassistant.helpers.config_validation as cv + +CONF_BODY_OFF = 'body_off' +CONF_BODY_ON = 'body_on' +DEFAULT_BODY_OFF = 'OFF' +DEFAULT_BODY_ON = 'ON' +DEFAULT_NAME = 'REST Switch' + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_BODY_OFF, default=DEFAULT_BODY_OFF): cv.string, + vol.Optional(CONF_BODY_ON, default=DEFAULT_BODY_ON): cv.string, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, +}) _LOGGER = logging.getLogger(__name__) -DEFAULT_NAME = "REST Switch" -DEFAULT_BODY_ON = "ON" -DEFAULT_BODY_OFF = "OFF" - # pylint: disable=unused-argument, def setup_platform(hass, config, add_devices_callback, discovery_info=None): - """Setup the REST switch.""" - resource = config.get('resource') - - if resource is None: - _LOGGER.error("Missing required variable: resource") - return False + """Setup the RESTful switch.""" + name = config.get(CONF_NAME) + resource = config.get(CONF_RESOURCE) + body_on = config.get(CONF_BODY_ON) + body_off = config.get(CONF_BODY_OFF) try: requests.get(resource, timeout=10) @@ -36,12 +47,7 @@ def setup_platform(hass, config, add_devices_callback, discovery_info=None): _LOGGER.error("No route to resource/endpoint: %s", resource) return False - add_devices_callback([RestSwitch( - hass, - config.get('name', DEFAULT_NAME), - config.get('resource'), - config.get('body_on', DEFAULT_BODY_ON), - config.get('body_off', DEFAULT_BODY_OFF))]) + add_devices_callback([RestSwitch(hass, name, resource, body_on, body_off)]) # pylint: disable=too-many-arguments diff --git a/homeassistant/const.py b/homeassistant/const.py index d8c1f3d5a0d..13733d24e75 100644 --- a/homeassistant/const.py +++ b/homeassistant/const.py @@ -40,6 +40,7 @@ CONF_HOSTS = 'hosts' CONF_ICON = 'icon' CONF_LATITUDE = 'latitude' CONF_LONGITUDE = 'longitude' +CONF_METHOD = 'method' CONF_MONITORED_CONDITIONS = 'monitored_conditions' CONF_MONITORED_VARIABLES = 'monitored_variables' CONF_NAME = 'name' @@ -53,6 +54,7 @@ CONF_PORT = 'port' CONF_RESOURCE = 'resource' CONF_RESOURCES = 'resources' CONF_SCAN_INTERVAL = 'scan_interval' +CONF_SENSOR_CLASS = 'sensor_class' CONF_STATE = 'state' CONF_TEMPERATURE_UNIT = 'temperature_unit' CONF_TIME_ZONE = 'time_zone'