diff --git a/homeassistant/components/binary_sensor/template.py b/homeassistant/components/binary_sensor/template.py index 612177533b7..0c41534f1f2 100644 --- a/homeassistant/components/binary_sensor/template.py +++ b/homeassistant/components/binary_sensor/template.py @@ -9,11 +9,13 @@ import logging from homeassistant.components.binary_sensor import (BinarySensorDevice, ENTITY_ID_FORMAT, SENSOR_CLASSES) -from homeassistant.const import ATTR_FRIENDLY_NAME, CONF_VALUE_TEMPLATE +from homeassistant.const import (ATTR_FRIENDLY_NAME, CONF_VALUE_TEMPLATE, + ATTR_ENTITY_ID, MATCH_ALL) from homeassistant.core import EVENT_STATE_CHANGED 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' @@ -52,13 +54,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None): 'Missing %s for sensor %s', CONF_VALUE_TEMPLATE, device) continue + entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL) + sensors.append( BinarySensorTemplate( hass, device, friendly_name, sensor_class, - value_template) + value_template, + entity_ids) ) if not sensors: _LOGGER.error('No sensors added') @@ -73,7 +78,7 @@ class BinarySensorTemplate(BinarySensorDevice): # pylint: disable=too-many-arguments def __init__(self, hass, device, friendly_name, sensor_class, - value_template): + value_template, entity_ids): """Initialize the Template binary sensor.""" self.hass = hass self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device, @@ -85,12 +90,13 @@ class BinarySensorTemplate(BinarySensorDevice): self.update() - def template_bsensor_event_listener(event): + def template_bsensor_state_listener(self, entity, old_state, + new_state): """Called when the target device changes state.""" self.update_ha_state(True) - hass.bus.listen(EVENT_STATE_CHANGED, - template_bsensor_event_listener) + track_state_change(hass, entity_ids, + template_bsensor_state_listener) @property def name(self): diff --git a/homeassistant/components/sensor/template.py b/homeassistant/components/sensor/template.py index b2b702646cb..5cfd5bd9c86 100644 --- a/homeassistant/components/sensor/template.py +++ b/homeassistant/components/sensor/template.py @@ -8,11 +8,13 @@ import logging from homeassistant.components.sensor import ENTITY_ID_FORMAT from homeassistant.const import ( - ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE) + ATTR_FRIENDLY_NAME, ATTR_UNIT_OF_MEASUREMENT, CONF_VALUE_TEMPLATE, + ATTR_ENTITY_ID, MATCH_ALL) from homeassistant.core import EVENT_STATE_CHANGED from homeassistant.exceptions import TemplateError from homeassistant.helpers.entity import Entity, generate_entity_id from homeassistant.helpers import template +from homeassistant.helpers.event import track_state_change from homeassistant.util import slugify _LOGGER = logging.getLogger(__name__) @@ -45,13 +47,16 @@ def setup_platform(hass, config, add_devices, discovery_info=None): "Missing %s for sensor %s", CONF_VALUE_TEMPLATE, device) continue + entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL) + sensors.append( SensorTemplate( hass, device, friendly_name, unit_of_measurement, - state_template) + state_template, + entity_ids) ) if not sensors: _LOGGER.error("No sensors added") @@ -65,7 +70,7 @@ class SensorTemplate(Entity): # pylint: disable=too-many-arguments def __init__(self, hass, device_id, friendly_name, unit_of_measurement, - state_template): + state_template, entity_ids): """Initialize the sensor.""" self.hass = hass self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id, @@ -77,11 +82,12 @@ class SensorTemplate(Entity): self.update() - def template_sensor_event_listener(event): + def template_sensor_state_listener(self, entity, old_state, new_state): """Called when the target device changes state.""" self.update_ha_state(True) - hass.bus.listen(EVENT_STATE_CHANGED, template_sensor_event_listener) + track_state_change(hass, entity_ids, + template_sensor_state_listener) @property def name(self): diff --git a/homeassistant/components/switch/template.py b/homeassistant/components/switch/template.py index 68aa1c3bd69..b088c5604cf 100644 --- a/homeassistant/components/switch/template.py +++ b/homeassistant/components/switch/template.py @@ -8,12 +8,14 @@ import logging from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchDevice from homeassistant.const import ( - ATTR_FRIENDLY_NAME, CONF_VALUE_TEMPLATE, STATE_OFF, STATE_ON) + ATTR_FRIENDLY_NAME, CONF_VALUE_TEMPLATE, STATE_OFF, STATE_ON, + ATTR_ENTITY_ID, MATCH_ALL) from homeassistant.core import EVENT_STATE_CHANGED from homeassistant.exceptions import TemplateError from homeassistant.helpers.entity import generate_entity_id from homeassistant.helpers.service import call_from_config from homeassistant.helpers import template +from homeassistant.helpers.event import track_state_change from homeassistant.util import slugify CONF_SWITCHES = 'switches' @@ -58,6 +60,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): "Missing action for switch %s", device) continue + entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL) + switches.append( SwitchTemplate( hass, @@ -65,7 +69,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None): friendly_name, state_template, on_action, - off_action) + off_action, + entity_ids) ) if not switches: _LOGGER.error("No switches added") @@ -79,7 +84,7 @@ class SwitchTemplate(SwitchDevice): # pylint: disable=too-many-arguments def __init__(self, hass, device_id, friendly_name, state_template, - on_action, off_action): + on_action, off_action, entity_ids): """Initialize the Template switch.""" self.hass = hass self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id, @@ -92,12 +97,12 @@ class SwitchTemplate(SwitchDevice): self.update() - def template_switch_event_listener(event): + def template_switch_state_listener(self, entity, old_state, new_state): """Called when the target device changes state.""" self.update_ha_state(True) - hass.bus.listen(EVENT_STATE_CHANGED, - template_switch_event_listener) + track_state_change(hass, entity_ids, + template_switch_state_listener) @property def name(self): diff --git a/tests/components/binary_sensor/test_template.py b/tests/components/binary_sensor/test_template.py index 478439209f5..262d011f90d 100644 --- a/tests/components/binary_sensor/test_template.py +++ b/tests/components/binary_sensor/test_template.py @@ -29,7 +29,7 @@ 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 }}') + 'motion', '{{ foo }}', None) add_devices.assert_called_once_with([mock_template.return_value]) def test_setup_no_sensors(self): @@ -77,7 +77,7 @@ class TestBinarySensorTemplate(unittest.TestCase): """"Test the attributes.""" hass = mock.MagicMock() vs = template.BinarySensorTemplate(hass, 'parent', 'Parent', - 'motion', '{{ 1 > 1 }}') + 'motion', '{{ 1 > 1 }}', None) self.assertFalse(vs.should_poll) self.assertEqual('motion', vs.sensor_class) self.assertEqual('Parent', vs.name) @@ -93,7 +93,7 @@ class TestBinarySensorTemplate(unittest.TestCase): """"Test the event.""" hass = get_test_home_assistant() vs = template.BinarySensorTemplate(hass, 'parent', 'Parent', - 'motion', '{{ 1 > 1 }}') + 'motion', '{{ 1 > 1 }}', None) vs.update_ha_state() hass.pool.block_till_done() @@ -110,7 +110,7 @@ class TestBinarySensorTemplate(unittest.TestCase): """"Test the template update error.""" hass = mock.MagicMock() vs = template.BinarySensorTemplate(hass, 'parent', 'Parent', - 'motion', '{{ 1 > 1 }}') + 'motion', '{{ 1 > 1 }}', None) mock_render.side_effect = TemplateError('foo') vs.update() mock_render.side_effect = TemplateError(