List entity_ids in config and only react to them (#2144)

* List entity_ids in config and only react to them

This allows us to define a list of entity_ids in the config to make the
template sensor, binary sensor and switch only react to state changes of
these entities instead of listening to all state changes.

* Forgot to import the track_state_change function

* Changed test for added entity_ids to config

* Use default MATCH_ALL and remove event_listener
This commit is contained in:
Bart274 2016-05-29 23:34:21 +02:00 committed by Paulus Schoutsen
parent 19522b1f39
commit 65fbba0e79
4 changed files with 38 additions and 21 deletions

View file

@ -9,11 +9,13 @@ import logging
from homeassistant.components.binary_sensor import (BinarySensorDevice, from homeassistant.components.binary_sensor import (BinarySensorDevice,
ENTITY_ID_FORMAT, ENTITY_ID_FORMAT,
SENSOR_CLASSES) 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.core import EVENT_STATE_CHANGED
from homeassistant.exceptions import TemplateError from homeassistant.exceptions import TemplateError
from homeassistant.helpers.entity import generate_entity_id from homeassistant.helpers.entity import generate_entity_id
from homeassistant.helpers import template from homeassistant.helpers import template
from homeassistant.helpers.event import track_state_change
from homeassistant.util import slugify from homeassistant.util import slugify
CONF_SENSORS = 'sensors' 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) 'Missing %s for sensor %s', CONF_VALUE_TEMPLATE, device)
continue continue
entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL)
sensors.append( sensors.append(
BinarySensorTemplate( BinarySensorTemplate(
hass, hass,
device, device,
friendly_name, friendly_name,
sensor_class, sensor_class,
value_template) value_template,
entity_ids)
) )
if not sensors: if not sensors:
_LOGGER.error('No sensors added') _LOGGER.error('No sensors added')
@ -73,7 +78,7 @@ class BinarySensorTemplate(BinarySensorDevice):
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
def __init__(self, hass, device, friendly_name, sensor_class, def __init__(self, hass, device, friendly_name, sensor_class,
value_template): value_template, entity_ids):
"""Initialize the Template binary sensor.""" """Initialize the Template binary sensor."""
self.hass = hass self.hass = hass
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device, self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device,
@ -85,12 +90,13 @@ class BinarySensorTemplate(BinarySensorDevice):
self.update() 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.""" """Called when the target device changes state."""
self.update_ha_state(True) self.update_ha_state(True)
hass.bus.listen(EVENT_STATE_CHANGED, track_state_change(hass, entity_ids,
template_bsensor_event_listener) template_bsensor_state_listener)
@property @property
def name(self): def name(self):

View file

@ -8,11 +8,13 @@ import logging
from homeassistant.components.sensor import ENTITY_ID_FORMAT from homeassistant.components.sensor import ENTITY_ID_FORMAT
from homeassistant.const import ( 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.core import EVENT_STATE_CHANGED
from homeassistant.exceptions import TemplateError from homeassistant.exceptions import TemplateError
from homeassistant.helpers.entity import Entity, generate_entity_id from homeassistant.helpers.entity import Entity, generate_entity_id
from homeassistant.helpers import template from homeassistant.helpers import template
from homeassistant.helpers.event import track_state_change
from homeassistant.util import slugify from homeassistant.util import slugify
_LOGGER = logging.getLogger(__name__) _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) "Missing %s for sensor %s", CONF_VALUE_TEMPLATE, device)
continue continue
entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL)
sensors.append( sensors.append(
SensorTemplate( SensorTemplate(
hass, hass,
device, device,
friendly_name, friendly_name,
unit_of_measurement, unit_of_measurement,
state_template) state_template,
entity_ids)
) )
if not sensors: if not sensors:
_LOGGER.error("No sensors added") _LOGGER.error("No sensors added")
@ -65,7 +70,7 @@ class SensorTemplate(Entity):
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
def __init__(self, hass, device_id, friendly_name, unit_of_measurement, def __init__(self, hass, device_id, friendly_name, unit_of_measurement,
state_template): state_template, entity_ids):
"""Initialize the sensor.""" """Initialize the sensor."""
self.hass = hass self.hass = hass
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id, self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id,
@ -77,11 +82,12 @@ class SensorTemplate(Entity):
self.update() 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.""" """Called when the target device changes state."""
self.update_ha_state(True) 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 @property
def name(self): def name(self):

View file

@ -8,12 +8,14 @@ import logging
from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchDevice from homeassistant.components.switch import ENTITY_ID_FORMAT, SwitchDevice
from homeassistant.const import ( 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.core import EVENT_STATE_CHANGED
from homeassistant.exceptions import TemplateError from homeassistant.exceptions import TemplateError
from homeassistant.helpers.entity import generate_entity_id from homeassistant.helpers.entity import generate_entity_id
from homeassistant.helpers.service import call_from_config from homeassistant.helpers.service import call_from_config
from homeassistant.helpers import template from homeassistant.helpers import template
from homeassistant.helpers.event import track_state_change
from homeassistant.util import slugify from homeassistant.util import slugify
CONF_SWITCHES = 'switches' CONF_SWITCHES = 'switches'
@ -58,6 +60,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
"Missing action for switch %s", device) "Missing action for switch %s", device)
continue continue
entity_ids = device_config.get(ATTR_ENTITY_ID, MATCH_ALL)
switches.append( switches.append(
SwitchTemplate( SwitchTemplate(
hass, hass,
@ -65,7 +69,8 @@ def setup_platform(hass, config, add_devices, discovery_info=None):
friendly_name, friendly_name,
state_template, state_template,
on_action, on_action,
off_action) off_action,
entity_ids)
) )
if not switches: if not switches:
_LOGGER.error("No switches added") _LOGGER.error("No switches added")
@ -79,7 +84,7 @@ class SwitchTemplate(SwitchDevice):
# pylint: disable=too-many-arguments # pylint: disable=too-many-arguments
def __init__(self, hass, device_id, friendly_name, state_template, def __init__(self, hass, device_id, friendly_name, state_template,
on_action, off_action): on_action, off_action, entity_ids):
"""Initialize the Template switch.""" """Initialize the Template switch."""
self.hass = hass self.hass = hass
self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id, self.entity_id = generate_entity_id(ENTITY_ID_FORMAT, device_id,
@ -92,12 +97,12 @@ class SwitchTemplate(SwitchDevice):
self.update() 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.""" """Called when the target device changes state."""
self.update_ha_state(True) self.update_ha_state(True)
hass.bus.listen(EVENT_STATE_CHANGED, track_state_change(hass, entity_ids,
template_switch_event_listener) template_switch_state_listener)
@property @property
def name(self): def name(self):

View file

@ -29,7 +29,7 @@ class TestBinarySensorTemplate(unittest.TestCase):
result = template.setup_platform(hass, config, add_devices) result = template.setup_platform(hass, config, add_devices)
self.assertTrue(result) self.assertTrue(result)
mock_template.assert_called_once_with(hass, 'test', 'virtual thingy', 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]) add_devices.assert_called_once_with([mock_template.return_value])
def test_setup_no_sensors(self): def test_setup_no_sensors(self):
@ -77,7 +77,7 @@ class TestBinarySensorTemplate(unittest.TestCase):
""""Test the attributes.""" """"Test the attributes."""
hass = mock.MagicMock() hass = mock.MagicMock()
vs = template.BinarySensorTemplate(hass, 'parent', 'Parent', vs = template.BinarySensorTemplate(hass, 'parent', 'Parent',
'motion', '{{ 1 > 1 }}') 'motion', '{{ 1 > 1 }}', None)
self.assertFalse(vs.should_poll) self.assertFalse(vs.should_poll)
self.assertEqual('motion', vs.sensor_class) self.assertEqual('motion', vs.sensor_class)
self.assertEqual('Parent', vs.name) self.assertEqual('Parent', vs.name)
@ -93,7 +93,7 @@ class TestBinarySensorTemplate(unittest.TestCase):
""""Test the event.""" """"Test the event."""
hass = get_test_home_assistant() hass = get_test_home_assistant()
vs = template.BinarySensorTemplate(hass, 'parent', 'Parent', vs = template.BinarySensorTemplate(hass, 'parent', 'Parent',
'motion', '{{ 1 > 1 }}') 'motion', '{{ 1 > 1 }}', None)
vs.update_ha_state() vs.update_ha_state()
hass.pool.block_till_done() hass.pool.block_till_done()
@ -110,7 +110,7 @@ class TestBinarySensorTemplate(unittest.TestCase):
""""Test the template update error.""" """"Test the template update error."""
hass = mock.MagicMock() hass = mock.MagicMock()
vs = template.BinarySensorTemplate(hass, 'parent', 'Parent', vs = template.BinarySensorTemplate(hass, 'parent', 'Parent',
'motion', '{{ 1 > 1 }}') 'motion', '{{ 1 > 1 }}', None)
mock_render.side_effect = TemplateError('foo') mock_render.side_effect = TemplateError('foo')
vs.update() vs.update()
mock_render.side_effect = TemplateError( mock_render.side_effect = TemplateError(