diff --git a/homeassistant/core.py b/homeassistant/core.py index 31bb281aeaa..30be92af153 100644 --- a/homeassistant/core.py +++ b/homeassistant/core.py @@ -387,7 +387,7 @@ class EventBus(object): @callback def async_fire(self, event_type: str, event_data=None, - origin=EventOrigin.local, wait=False): + origin=EventOrigin.local): """Fire an event. This method must be run in the event loop. @@ -395,8 +395,10 @@ class EventBus(object): listeners = self._listeners.get(event_type, []) # EVENT_HOMEASSISTANT_CLOSE should go only to his listeners - if event_type != EVENT_HOMEASSISTANT_CLOSE: - listeners = self._listeners.get(MATCH_ALL, []) + listeners + match_all_listeners = self._listeners.get(MATCH_ALL) + if (match_all_listeners is not None and + event_type != EVENT_HOMEASSISTANT_CLOSE): + listeners = match_all_listeners + listeners event = Event(event_type, event_data, origin) @@ -673,15 +675,6 @@ class StateMachine(object): state_obj = self.get(entity_id) return state_obj is not None and state_obj.state == state - def is_state_attr(self, entity_id, name, value): - """Test if entity exists and has a state attribute set to value. - - Async friendly. - """ - state_obj = self.get(entity_id) - return state_obj is not None and \ - state_obj.attributes.get(name, None) == value - def remove(self, entity_id): """Remove the state of an entity. diff --git a/homeassistant/helpers/entity.py b/homeassistant/helpers/entity.py index da82fc9202f..8e032bc48a1 100644 --- a/homeassistant/helpers/entity.py +++ b/homeassistant/helpers/entity.py @@ -168,15 +168,9 @@ class Entity(object): def update(self): """Retrieve latest state. - When not implemented, will forward call to async version if available. + For asyncio use coroutine async_update. """ - async_update = getattr(self, 'async_update', None) - - if async_update is None: - return - - # pylint: disable=not-callable - run_coroutine_threadsafe(async_update(), self.hass.loop).result() + pass # DO NOT OVERWRITE # These properties and methods are either managed by Home Assistant or they diff --git a/homeassistant/helpers/template.py b/homeassistant/helpers/template.py index 6f83688623a..bf1b88e1c3f 100644 --- a/homeassistant/helpers/template.py +++ b/homeassistant/helpers/template.py @@ -107,7 +107,8 @@ class Template(object): This method must be run in the event loop. """ - self._ensure_compiled() + if self._compiled is None: + self._ensure_compiled() if variables is not None: kwargs.update(variables) @@ -135,7 +136,8 @@ class Template(object): This method must be run in the event loop. """ - self._ensure_compiled() + if self._compiled is None: + self._ensure_compiled() variables = { 'value': value @@ -154,20 +156,17 @@ class Template(object): def _ensure_compiled(self): """Bind a template to a specific hass instance.""" - if self._compiled is not None: - return - self.ensure_valid() assert self.hass is not None, 'hass variable not set on template' - location_methods = LocationMethods(self.hass) + template_methods = TemplateMethods(self.hass) global_vars = ENV.make_globals({ - 'closest': location_methods.closest, - 'distance': location_methods.distance, + 'closest': template_methods.closest, + 'distance': template_methods.distance, 'is_state': self.hass.states.is_state, - 'is_state_attr': self.hass.states.is_state_attr, + 'is_state_attr': template_methods.is_state_attr, 'states': AllStates(self.hass), }) @@ -272,11 +271,11 @@ def _wrap_state(state): return None if state is None else TemplateState(state) -class LocationMethods(object): - """Class to expose distance helpers to templates.""" +class TemplateMethods(object): + """Class to expose helpers to templates.""" def __init__(self, hass): - """Initialize the distance helpers.""" + """Initialize the helpers.""" self._hass = hass def closest(self, *args): @@ -390,6 +389,12 @@ class LocationMethods(object): return self._hass.config.units.length( loc_util.distance(*locations[0] + locations[1]), 'm') + def is_state_attr(self, entity_id, name, value): + """Test if a state is a specific attribute.""" + state_obj = self._hass.states.get(entity_id) + return state_obj is not None and \ + state_obj.attributes.get(name) == value + def _resolve_state(self, entity_id_or_state): """Return state or entity_id if given.""" if isinstance(entity_id_or_state, State): diff --git a/tests/components/alarm_control_panel/test_manual.py b/tests/components/alarm_control_panel/test_manual.py index b5af01584d3..1b10b942281 100644 --- a/tests/components/alarm_control_panel/test_manual.py +++ b/tests/components/alarm_control_panel/test_manual.py @@ -72,10 +72,8 @@ class TestAlarmControlPanelManual(unittest.TestCase): self.assertEqual(STATE_ALARM_PENDING, self.hass.states.get(entity_id).state) - self.assertTrue( - self.hass.states.is_state_attr(entity_id, - 'post_pending_state', - STATE_ALARM_ARMED_HOME)) + state = self.hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_HOME future = dt_util.utcnow() + timedelta(seconds=1) with patch(('homeassistant.components.alarm_control_panel.manual.' @@ -83,8 +81,8 @@ class TestAlarmControlPanelManual(unittest.TestCase): fire_time_changed(self.hass, future) self.hass.block_till_done() - self.assertEqual(STATE_ALARM_ARMED_HOME, - self.hass.states.get(entity_id).state) + state = self.hass.states.get(entity_id) + assert state.state == STATE_ALARM_ARMED_HOME def test_arm_home_with_invalid_code(self): """Attempt to arm home without a valid code.""" @@ -155,10 +153,8 @@ class TestAlarmControlPanelManual(unittest.TestCase): self.assertEqual(STATE_ALARM_PENDING, self.hass.states.get(entity_id).state) - self.assertTrue( - self.hass.states.is_state_attr(entity_id, - 'post_pending_state', - STATE_ALARM_ARMED_AWAY)) + state = self.hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_AWAY future = dt_util.utcnow() + timedelta(seconds=1) with patch(('homeassistant.components.alarm_control_panel.manual.' @@ -166,8 +162,8 @@ class TestAlarmControlPanelManual(unittest.TestCase): fire_time_changed(self.hass, future) self.hass.block_till_done() - self.assertEqual(STATE_ALARM_ARMED_AWAY, - self.hass.states.get(entity_id).state) + state = self.hass.states.get(entity_id) + assert state.state == STATE_ALARM_ARMED_AWAY def test_arm_away_with_invalid_code(self): """Attempt to arm away without a valid code.""" @@ -238,10 +234,9 @@ class TestAlarmControlPanelManual(unittest.TestCase): self.assertEqual(STATE_ALARM_PENDING, self.hass.states.get(entity_id).state) - self.assertTrue( - self.hass.states.is_state_attr(entity_id, - 'post_pending_state', - STATE_ALARM_ARMED_NIGHT)) + state = self.hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == \ + STATE_ALARM_ARMED_NIGHT future = dt_util.utcnow() + timedelta(seconds=1) with patch(('homeassistant.components.alarm_control_panel.manual.' @@ -249,8 +244,8 @@ class TestAlarmControlPanelManual(unittest.TestCase): fire_time_changed(self.hass, future) self.hass.block_till_done() - self.assertEqual(STATE_ALARM_ARMED_NIGHT, - self.hass.states.get(entity_id).state) + state = self.hass.states.get(entity_id) + assert state.state == STATE_ALARM_ARMED_NIGHT def test_arm_night_with_invalid_code(self): """Attempt to night home without a valid code.""" @@ -329,10 +324,8 @@ class TestAlarmControlPanelManual(unittest.TestCase): self.assertEqual(STATE_ALARM_PENDING, self.hass.states.get(entity_id).state) - self.assertTrue( - self.hass.states.is_state_attr(entity_id, - 'post_pending_state', - STATE_ALARM_TRIGGERED)) + state = self.hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED future = dt_util.utcnow() + timedelta(seconds=2) with patch(('homeassistant.components.alarm_control_panel.manual.' @@ -340,8 +333,8 @@ class TestAlarmControlPanelManual(unittest.TestCase): fire_time_changed(self.hass, future) self.hass.block_till_done() - self.assertEqual(STATE_ALARM_TRIGGERED, - self.hass.states.get(entity_id).state) + state = self.hass.states.get(entity_id) + assert state.state == STATE_ALARM_TRIGGERED future = dt_util.utcnow() + timedelta(seconds=5) with patch(('homeassistant.components.alarm_control_panel.manual.' @@ -349,8 +342,8 @@ class TestAlarmControlPanelManual(unittest.TestCase): fire_time_changed(self.hass, future) self.hass.block_till_done() - self.assertEqual(STATE_ALARM_DISARMED, - self.hass.states.get(entity_id).state) + state = self.hass.states.get(entity_id) + assert state.state == STATE_ALARM_DISARMED def test_armed_home_with_specific_pending(self): """Test arm home method.""" diff --git a/tests/components/alarm_control_panel/test_manual_mqtt.py b/tests/components/alarm_control_panel/test_manual_mqtt.py index 5210c616f9c..e56b6865e6e 100644 --- a/tests/components/alarm_control_panel/test_manual_mqtt.py +++ b/tests/components/alarm_control_panel/test_manual_mqtt.py @@ -100,10 +100,8 @@ class TestAlarmControlPanelManualMqtt(unittest.TestCase): self.assertEqual(STATE_ALARM_PENDING, self.hass.states.get(entity_id).state) - self.assertTrue( - self.hass.states.is_state_attr(entity_id, - 'post_pending_state', - STATE_ALARM_ARMED_HOME)) + state = self.hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_HOME future = dt_util.utcnow() + timedelta(seconds=1) with patch(('homeassistant.components.alarm_control_panel.manual_mqtt.' @@ -189,10 +187,8 @@ class TestAlarmControlPanelManualMqtt(unittest.TestCase): self.assertEqual(STATE_ALARM_PENDING, self.hass.states.get(entity_id).state) - self.assertTrue( - self.hass.states.is_state_attr(entity_id, - 'post_pending_state', - STATE_ALARM_ARMED_AWAY)) + state = self.hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_ARMED_AWAY future = dt_util.utcnow() + timedelta(seconds=1) with patch(('homeassistant.components.alarm_control_panel.manual_mqtt.' @@ -278,10 +274,9 @@ class TestAlarmControlPanelManualMqtt(unittest.TestCase): self.assertEqual(STATE_ALARM_PENDING, self.hass.states.get(entity_id).state) - self.assertTrue( - self.hass.states.is_state_attr(entity_id, - 'post_pending_state', - STATE_ALARM_ARMED_NIGHT)) + state = self.hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == \ + STATE_ALARM_ARMED_NIGHT future = dt_util.utcnow() + timedelta(seconds=1) with patch(('homeassistant.components.alarm_control_panel.manual_mqtt.' @@ -375,10 +370,8 @@ class TestAlarmControlPanelManualMqtt(unittest.TestCase): self.assertEqual(STATE_ALARM_PENDING, self.hass.states.get(entity_id).state) - self.assertTrue( - self.hass.states.is_state_attr(entity_id, - 'post_pending_state', - STATE_ALARM_TRIGGERED)) + state = self.hass.states.get(entity_id) + assert state.attributes['post_pending_state'] == STATE_ALARM_TRIGGERED future = dt_util.utcnow() + timedelta(seconds=2) with patch(('homeassistant.components.alarm_control_panel.manual_mqtt.' diff --git a/tests/helpers/test_entity.py b/tests/helpers/test_entity.py index d7f518f489e..a4c8b03daa0 100644 --- a/tests/helpers/test_entity.py +++ b/tests/helpers/test_entity.py @@ -100,22 +100,6 @@ class TestHelpersEntity(object): fmt, 'overwrite hidden true', hass=self.hass) == 'test.overwrite_hidden_true_2' - def test_update_calls_async_update_if_available(self): - """Test async update getting called.""" - async_update = [] - - class AsyncEntity(entity.Entity): - hass = self.hass - entity_id = 'sensor.test' - - @asyncio.coroutine - def async_update(self): - async_update.append([1]) - - ent = AsyncEntity() - ent.update() - assert len(async_update) == 1 - def test_device_class(self): """Test device class attribute.""" state = self.hass.states.get(self.entity.entity_id) diff --git a/tests/test_core.py b/tests/test_core.py index c3fea749f5d..09ddf721628 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -495,18 +495,6 @@ class TestStateMachine(unittest.TestCase): self.assertFalse(self.states.is_state('light.Bowl', 'off')) self.assertFalse(self.states.is_state('light.Non_existing', 'on')) - def test_is_state_attr(self): - """Test is_state_attr method.""" - self.states.set("light.Bowl", "on", {"brightness": 100}) - self.assertTrue( - self.states.is_state_attr('light.Bowl', 'brightness', 100)) - self.assertFalse( - self.states.is_state_attr('light.Bowl', 'friendly_name', 200)) - self.assertFalse( - self.states.is_state_attr('light.Bowl', 'friendly_name', 'Bowl')) - self.assertFalse( - self.states.is_state_attr('light.Non_existing', 'brightness', 100)) - def test_entity_ids(self): """Test get_entity_ids method.""" ent_ids = self.states.entity_ids()