diff --git a/homeassistant/components/binary_sensor/template.py b/homeassistant/components/binary_sensor/template.py index ee68e817275..e87594e625c 100644 --- a/homeassistant/components/binary_sensor/template.py +++ b/homeassistant/components/binary_sensor/template.py @@ -5,55 +5,47 @@ For more details about this platform, please refer to the documentation at https://home-assistant.io/components/binary_sensor.template/ """ import logging +import voluptuous as vol +import homeassistant.helpers.config_validation as cv from homeassistant.components.binary_sensor import (BinarySensorDevice, ENTITY_ID_FORMAT, - SENSOR_CLASSES) -from homeassistant.const import (ATTR_FRIENDLY_NAME, CONF_VALUE_TEMPLATE, - ATTR_ENTITY_ID, MATCH_ALL) + PLATFORM_SCHEMA, + SENSOR_CLASSES_SCHEMA) + +from homeassistant.const import (ATTR_FRIENDLY_NAME, ATTR_ENTITY_ID, MATCH_ALL, + CONF_VALUE_TEMPLATE, CONF_SENSOR_CLASS) from homeassistant.exceptions import TemplateError from homeassistant.helpers.entity import generate_entity_id from homeassistant.helpers import template from homeassistant.helpers.event import track_state_change -from homeassistant.util import slugify CONF_SENSORS = 'sensors' + +SENSOR_SCHEMA = vol.Schema({ + vol.Required(CONF_VALUE_TEMPLATE): cv.template, + vol.Optional(ATTR_FRIENDLY_NAME): cv.string, + vol.Optional(ATTR_ENTITY_ID, default=MATCH_ALL): cv.entity_ids, + vol.Optional(CONF_SENSOR_CLASS, default=None): SENSOR_CLASSES_SCHEMA +}) + +PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({ + vol.Required(CONF_SENSORS): vol.Schema({cv.slug: SENSOR_SCHEMA}), +}) + _LOGGER = logging.getLogger(__name__) def setup_platform(hass, config, add_devices, discovery_info=None): """Setup template binary sensors.""" sensors = [] - if config.get(CONF_SENSORS) is None: - _LOGGER.error('Missing configuration data for binary_sensor platform') - return False for device, device_config in config[CONF_SENSORS].items(): - if device != slugify(device): - _LOGGER.error('Found invalid key for binary_sensor.template: %s. ' - 'Use %s instead', device, slugify(device)) - continue - - if not isinstance(device_config, dict): - _LOGGER.error('Missing configuration data for binary_sensor %s', - device) - continue - + value_template = device_config[CONF_VALUE_TEMPLATE] + entity_ids = device_config[ATTR_ENTITY_ID] friendly_name = device_config.get(ATTR_FRIENDLY_NAME, device) - sensor_class = device_config.get('sensor_class') - value_template = device_config.get(CONF_VALUE_TEMPLATE) - - if sensor_class not in SENSOR_CLASSES: - _LOGGER.error('Sensor class is not valid') - continue - - if value_template is None: - _LOGGER.error( - 'Missing %s for sensor %s', CONF_VALUE_TEMPLATE, device) - continue - - entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL) + sensor_class = device_config.get(CONF_SENSOR_CLASS) sensors.append( BinarySensorTemplate( diff --git a/tests/components/binary_sensor/test_template.py b/tests/components/binary_sensor/test_template.py index 634834779d5..0f08817f15a 100644 --- a/tests/components/binary_sensor/test_template.py +++ b/tests/components/binary_sensor/test_template.py @@ -3,6 +3,7 @@ import unittest from unittest import mock from homeassistant.const import EVENT_STATE_CHANGED, MATCH_ALL +import homeassistant.bootstrap as bootstrap from homeassistant.components.binary_sensor import template from homeassistant.exceptions import TemplateError @@ -21,6 +22,7 @@ class TestBinarySensorTemplate(unittest.TestCase): 'friendly_name': 'virtual thingy', 'value_template': '{{ foo }}', 'sensor_class': 'motion', + 'entity_id': 'test' }, } } @@ -29,48 +31,61 @@ class TestBinarySensorTemplate(unittest.TestCase): result = template.setup_platform(hass, config, add_devices) self.assertTrue(result) mock_template.assert_called_once_with(hass, 'test', 'virtual thingy', - 'motion', '{{ foo }}', MATCH_ALL) + 'motion', '{{ foo }}', 'test') add_devices.assert_called_once_with([mock_template.return_value]) def test_setup_no_sensors(self): """"Test setup with no sensors.""" - config = {} - result = template.setup_platform(None, config, None) + hass = mock.MagicMock() + result = bootstrap.setup_component(hass, 'sensor', { + 'sensor': { + 'platform': 'template' + } + }) self.assertFalse(result) def test_setup_invalid_device(self): """"Test the setup with invalid devices.""" - config = { - 'sensors': { - 'foo bar': {}, - }, - } - result = template.setup_platform(None, config, None) + hass = mock.MagicMock() + result = bootstrap.setup_component(hass, 'sensor', { + 'sensor': { + 'platform': 'template', + 'sensors': { + 'foo bar': {}, + }, + } + }) self.assertFalse(result) def test_setup_invalid_sensor_class(self): """"Test setup with invalid sensor class.""" - config = { - 'sensors': { - 'test': { - 'value_template': '{{ foo }}', - 'sensor_class': 'foobarnotreal', + hass = mock.MagicMock() + result = bootstrap.setup_component(hass, 'sensor', { + 'sensor': { + 'platform': 'template', + 'sensors': { + 'test': { + 'value_template': '{{ foo }}', + 'sensor_class': 'foobarnotreal', + }, }, - }, - } - result = template.setup_platform(None, config, None) + } + }) self.assertFalse(result) def test_setup_invalid_missing_template(self): """"Test setup with invalid and missing template.""" - config = { - 'sensors': { - 'test': { - 'sensor_class': 'motion', - }, - }, - } - result = template.setup_platform(None, config, None) + hass = mock.MagicMock() + result = bootstrap.setup_component(hass, 'sensor', { + 'sensor': { + 'platform': 'template', + 'sensors': { + 'test': { + 'sensor_class': 'motion', + }, + } + } + }) self.assertFalse(result) def test_attributes(self):