diff --git a/homeassistant/components/binary_sensor/arest.py b/homeassistant/components/binary_sensor/arest.py index 56362611514113..02f9d75c4041e1 100644 --- a/homeassistant/components/binary_sensor/arest.py +++ b/homeassistant/components/binary_sensor/arest.py @@ -1,5 +1,5 @@ """ -Support for exposed aREST RESTful API of a device. +Support for an exposed aREST RESTful API of a device. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/binary_sensor.arest/ @@ -8,31 +8,32 @@ from datetime import timedelta import requests +import voluptuous as vol from homeassistant.components.binary_sensor import ( - BinarySensorDevice, SENSOR_CLASSES) -from homeassistant.const import CONF_RESOURCE, CONF_PIN + BinarySensorDevice, PLATFORM_SCHEMA, SENSOR_CLASSES_SCHEMA) +from homeassistant.const import ( + CONF_RESOURCE, CONF_PIN, CONF_NAME, CONF_SENSOR_CLASS) from homeassistant.util import Throttle +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_NAME): cv.string, + vol.Required(CONF_PIN): cv.string, + vol.Optional(CONF_SENSOR_CLASS): SENSOR_CLASSES_SCHEMA, +}) + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the aREST binary sensor.""" resource = config.get(CONF_RESOURCE) pin = config.get(CONF_PIN) - - sensor_class = config.get('sensor_class') - if sensor_class not in SENSOR_CLASSES: - _LOGGER.warning('Unknown sensor class: %s', sensor_class) - sensor_class = None - - if None in (resource, pin): - _LOGGER.error('Not all required config keys present: %s', - ', '.join((CONF_RESOURCE, CONF_PIN))) - return False + sensor_class = config.get(CONF_SENSOR_CLASS) try: response = requests.get(resource, timeout=10).json() @@ -49,11 +50,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): arest = ArestData(resource, pin) add_devices([ArestBinarySensor( - arest, - resource, - config.get('name', response['name']), - sensor_class, - pin)]) + arest, resource, config.get(CONF_NAME, response[CONF_NAME]), + sensor_class, pin)]) # pylint: disable=too-many-instance-attributes, too-many-arguments diff --git a/homeassistant/components/sensor/arest.py b/homeassistant/components/sensor/arest.py index 782204d9d9a672..d9af686e3b0111 100644 --- a/homeassistant/components/sensor/arest.py +++ b/homeassistant/components/sensor/arest.py @@ -1,5 +1,5 @@ """ -The arest sensor will consume an exposed aREST API of a device. +Support for an exposed aREST RESTful API of a device. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/sensor.arest/ @@ -8,30 +8,48 @@ from datetime import timedelta import requests +import voluptuous as vol +from homeassistant.components.sensor import PLATFORM_SCHEMA from homeassistant.const import ( - ATTR_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE, DEVICE_DEFAULT_NAME, - CONF_RESOURCE, CONF_MONITORED_VARIABLES) + CONF_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE, CONF_RESOURCE, + CONF_MONITORED_VARIABLES, CONF_NAME, STATE_UNKNOWN) from homeassistant.exceptions import TemplateError from homeassistant.helpers.entity import Entity from homeassistant.helpers import template from homeassistant.util import Throttle +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) MIN_TIME_BETWEEN_UPDATES = timedelta(seconds=30) +CONF_FUNCTIONS = 'functions' +CONF_PINS = 'pins' + +DEFAULT_NAME = 'aREST sensor' + +PIN_VARIABLE_SCHEMA = vol.Schema({ + vol.Optional(CONF_NAME): cv.string, + vol.Optional(CONF_UNIT_OF_MEASUREMENT): cv.string, + vol.Optional(CONF_VALUE_TEMPLATE): cv.template, +}) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PINS, default={}): + vol.Schema({cv.string: PIN_VARIABLE_SCHEMA}), + vol.Optional(CONF_MONITORED_VARIABLES, default={}): + vol.Schema({cv.string: PIN_VARIABLE_SCHEMA}), +}) + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the aREST sensor.""" resource = config.get(CONF_RESOURCE) var_conf = config.get(CONF_MONITORED_VARIABLES) - pins = config.get('pins', None) - - if resource is None: - _LOGGER.error('Not all required config keys present: %s', - CONF_RESOURCE) - return False + pins = config.get(CONF_PINS) try: response = requests.get(resource, timeout=10).json() @@ -65,32 +83,26 @@ def _render(value): if var_conf is not None: for variable in var_conf: - if variable['name'] not in response['variables']: + if variable[CONF_NAME] not in response['variables']: _LOGGER.error('Variable: "%s" does not exist', - variable['name']) + variable[CONF_NAME]) continue renderer = make_renderer(variable.get(CONF_VALUE_TEMPLATE)) - dev.append(ArestSensor(arest, - resource, - config.get('name', response['name']), - variable['name'], - variable=variable['name'], - unit_of_measurement=variable.get( - ATTR_UNIT_OF_MEASUREMENT), - renderer=renderer)) + dev.append(ArestSensor( + arest, resource, config.get(CONF_NAME, response[CONF_NAME]), + variable[CONF_NAME], variable=variable[CONF_NAME], + unit_of_measurement=variable.get(CONF_UNIT_OF_MEASUREMENT), + renderer=renderer)) if pins is not None: for pinnum, pin in pins.items(): renderer = make_renderer(pin.get(CONF_VALUE_TEMPLATE)) - dev.append(ArestSensor(ArestData(resource, pinnum), - resource, - config.get('name', response['name']), - pin.get('name'), - pin=pinnum, - unit_of_measurement=pin.get( - ATTR_UNIT_OF_MEASUREMENT), - renderer=renderer)) + dev.append(ArestSensor( + ArestData(resource, pinnum), resource, + config.get(CONF_NAME, response[CONF_NAME]), pin.get(CONF_NAME), + pin=pinnum, unit_of_measurement=pin.get( + CONF_UNIT_OF_MEASUREMENT), renderer=renderer)) add_devices(dev) @@ -104,18 +116,17 @@ def __init__(self, arest, resource, location, name, variable=None, """Initialize the sensor.""" self.arest = arest self._resource = resource - self._name = '{} {}'.format(location.title(), name.title()) \ - or DEVICE_DEFAULT_NAME + self._name = '{} {}'.format(location.title(), name.title()) self._variable = variable self._pin = pin - self._state = 'n/a' + self._state = STATE_UNKNOWN self._unit_of_measurement = unit_of_measurement self._renderer = renderer self.update() if self._pin is not None: - request = requests.get('{}/mode/{}/i'.format - (self._resource, self._pin), timeout=10) + request = requests.get( + '{}/mode/{}/i'.format(self._resource, self._pin), timeout=10) if request.status_code is not 200: _LOGGER.error("Can't set mode. Is device offline?") @@ -137,9 +148,8 @@ def state(self): if 'error' in values: return values['error'] - value = self._renderer(values.get('value', - values.get(self._variable, - 'N/A'))) + value = self._renderer( + values.get('value', values.get(self._variable, STATE_UNKNOWN))) return value def update(self): diff --git a/homeassistant/components/switch/arest.py b/homeassistant/components/switch/arest.py index 18fabd3cb74908..ce5c946b43610e 100644 --- a/homeassistant/components/switch/arest.py +++ b/homeassistant/components/switch/arest.py @@ -1,5 +1,5 @@ """ -Support for device running with the aREST RESTful framework. +Support for an exposed aREST RESTful API of a device. For more details about this platform, please refer to the documentation at https://home-assistant.io/components/switch.arest/ @@ -8,17 +8,36 @@ import logging import requests +import voluptuous as vol -from homeassistant.components.switch import SwitchDevice -from homeassistant.const import ( - DEVICE_DEFAULT_NAME, CONF_NAME, CONF_RESOURCE) +from homeassistant.components.switch import (SwitchDevice, PLATFORM_SCHEMA) +from homeassistant.const import (CONF_NAME, CONF_RESOURCE) +import homeassistant.helpers.config_validation as cv _LOGGER = logging.getLogger(__name__) +CONF_FUNCTIONS = 'functions' +CONF_PINS = 'pins' + +DEFAULT_NAME = 'aREST switch' + +PIN_FUNCTION_SCHEMA = vol.Schema({ + vol.Optional(CONF_NAME): cv.string, +}) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_RESOURCE): cv.url, + vol.Optional(CONF_NAME, default=DEFAULT_NAME): cv.string, + vol.Optional(CONF_PINS, default={}): + vol.Schema({cv.string: PIN_FUNCTION_SCHEMA}), + vol.Optional(CONF_FUNCTIONS, default={}): + vol.Schema({cv.string: PIN_FUNCTION_SCHEMA}), +}) + def setup_platform(hass, config, add_devices, discovery_info=None): """Setup the aREST switches.""" - resource = config.get(CONF_RESOURCE, None) + resource = config.get(CONF_RESOURCE) try: response = requests.get(resource, timeout=10) @@ -33,29 +52,28 @@ def setup_platform(hass, config, add_devices, discovery_info=None): return False dev = [] - pins = config.get('pins', {}) + pins = config.get(CONF_PINS) for pinnum, pin in pins.items(): dev.append(ArestSwitchPin( - resource, config.get(CONF_NAME, response.json()['name']), - pin.get('name'), pinnum)) + resource, config.get(CONF_NAME, response.json()[CONF_NAME]), + pin.get(CONF_NAME), pinnum)) - functions = config.get('functions', {}) + functions = config.get(CONF_FUNCTIONS) for funcname, func in functions.items(): dev.append(ArestSwitchFunction( - resource, config.get(CONF_NAME, response.json()['name']), - func.get('name'), funcname)) + resource, config.get(CONF_NAME, response.json()[CONF_NAME]), + func.get(CONF_NAME), funcname)) add_devices(dev) class ArestSwitchBase(SwitchDevice): - """representation of an aREST switch.""" + """Representation of an aREST switch.""" def __init__(self, resource, location, name): """Initialize the switch.""" self._resource = resource - self._name = '{} {}'.format(location.title(), name.title()) \ - or DEVICE_DEFAULT_NAME + self._name = '{} {}'.format(location.title(), name.title()) self._state = None @property @@ -77,8 +95,8 @@ def __init__(self, resource, location, name, func): super().__init__(resource, location, name) self._func = func - request = requests.get('{}/{}'.format(self._resource, self._func), - timeout=10) + request = requests.get( + '{}/{}'.format(self._resource, self._func), timeout=10) if request.status_code is not 200: _LOGGER.error("Can't find function. Is device offline?") @@ -90,36 +108,36 @@ def __init__(self, resource, location, name, func): _LOGGER.error("No return_value received. " "Is the function name correct.") except ValueError: - _LOGGER.error("Response invalid. Is the function name correct.") + _LOGGER.error("Response invalid. Is the function name correct?") def turn_on(self, **kwargs): """Turn the device on.""" - request = requests.get('{}/{}'.format(self._resource, self._func), - timeout=10, params={"params": "1"}) + request = requests.get( + '{}/{}'.format(self._resource, self._func), timeout=10, + params={'params': '1'}) if request.status_code == 200: self._state = True else: _LOGGER.error("Can't turn on function %s at %s. " - "Is device offline?", - self._func, self._resource) + "Is device offline?", self._func, self._resource) def turn_off(self, **kwargs): """Turn the device off.""" - request = requests.get('{}/{}'.format(self._resource, self._func), - timeout=10, params={"params": "0"}) + request = requests.get( + '{}/{}'.format(self._resource, self._func), timeout=10, + params={'params': '0'}) if request.status_code == 200: self._state = False else: _LOGGER.error("Can't turn off function %s at %s. " - "Is device offline?", - self._func, self._resource) + "Is device offline?", self._func, self._resource) def update(self): """Get the latest data from aREST API and update the state.""" - request = requests.get('{}/{}'.format(self._resource, - self._func), timeout=10) + request = requests.get( + '{}/{}'.format(self._resource, self._func), timeout=10) self._state = request.json()['return_value'] != 0 @@ -131,15 +149,15 @@ def __init__(self, resource, location, name, pin): super().__init__(resource, location, name) self._pin = pin - request = requests.get('{}/mode/{}/o'.format(self._resource, - self._pin), timeout=10) + request = requests.get( + '{}/mode/{}/o'.format(self._resource, self._pin), timeout=10) if request.status_code is not 200: _LOGGER.error("Can't set mode. Is device offline?") def turn_on(self, **kwargs): """Turn the device on.""" - request = requests.get('{}/digital/{}/1'.format(self._resource, - self._pin), timeout=10) + request = requests.get( + '{}/digital/{}/1'.format(self._resource, self._pin), timeout=10) if request.status_code == 200: self._state = True else: @@ -148,8 +166,8 @@ def turn_on(self, **kwargs): def turn_off(self, **kwargs): """Turn the device off.""" - request = requests.get('{}/digital/{}/0'.format(self._resource, - self._pin), timeout=10) + request = requests.get( + '{}/digital/{}/0'.format(self._resource, self._pin), timeout=10) if request.status_code == 200: self._state = False else: @@ -158,6 +176,6 @@ def turn_off(self, **kwargs): def update(self): """Get the latest data from aREST API and update the state.""" - request = requests.get('{}/digital/{}'.format(self._resource, - self._pin), timeout=10) + request = requests.get( + '{}/digital/{}'.format(self._resource, self._pin), timeout=10) self._state = request.json()['return_value'] != 0