diff --git a/homeassistant/__init__.py b/homeassistant/__init__.py index 8ebbe16f41d..c9e8013b4eb 100644 --- a/homeassistant/__init__.py +++ b/homeassistant/__init__.py @@ -100,14 +100,6 @@ class HomeAssistant(object): self.bus.fire(EVENT_CALL_SERVICE, event_data) - def get_entity_ids(self, domain_filter=None): - """ Returns known entity ids. """ - if domain_filter: - return [entity_id for entity_id in self.states.entity_ids - if entity_id.startswith(domain_filter)] - else: - return self.states.entity_ids - def track_state_change(self, entity_ids, action, from_state=None, to_state=None): """ @@ -202,31 +194,6 @@ class HomeAssistant(object): self.bus.listen(EVENT_TIME_CHANGED, time_listener) - def listen_once_event(self, event_type, listener): - """ Listen once for event of a specific type. - - To listen to all events specify the constant ``MATCH_ALL`` - as event_type. - - Note: at the moment it is impossible to remove a one time listener. - """ - @ft.wraps(listener) - def onetime_listener(event): - """ Removes listener from eventbus and then fires listener. """ - if not hasattr(onetime_listener, 'run'): - # Set variable so that we will never run twice. - # Because the event bus might have to wait till a thread comes - # available to execute this listener it might occur that the - # listener gets lined up twice to be executed. - # This will make sure the second time it does nothing. - onetime_listener.run = True - - self.bus.remove_listener(event_type, onetime_listener) - - listener(event) - - self.bus.listen(event_type, onetime_listener) - def stop(self): """ Stops Home Assistant and shuts down all threads. """ _LOGGER.info("Stopping") @@ -238,6 +205,32 @@ class HomeAssistant(object): self._pool.stop() + def get_entity_ids(self, domain_filter=None): + """ + Returns known entity ids. + + THIS METHOD IS DEPRECATED. Use hass.states.entity_ids + """ + _LOGGER.warning( + "hass.get_entiy_ids is deprecated. Use hass.states.entity_ids") + + return self.states.entity_ids(domain_filter) + + def listen_once_event(self, event_type, listener): + """ Listen once for event of a specific type. + + To listen to all events specify the constant ``MATCH_ALL`` + as event_type. + + Note: at the moment it is impossible to remove a one time listener. + + THIS METHOD IS DEPRECATED. Please use hass.events.listen_once. + """ + _LOGGER.warning( + "hass.listen_once_event is deprecated. Use hass.bus.listen_once") + + self.bus.listen_once(event_type, listener) + def _process_match_param(parameter): """ Wraps parameter in a list if it is not one and returns it. """ @@ -390,6 +383,31 @@ class EventBus(object): else: self._listeners[event_type] = [listener] + def listen_once(self, event_type, listener): + """ Listen once for event of a specific type. + + To listen to all events specify the constant ``MATCH_ALL`` + as event_type. + + Note: at the moment it is impossible to remove a one time listener. + """ + @ft.wraps(listener) + def onetime_listener(event): + """ Removes listener from eventbus and then fires listener. """ + if not hasattr(onetime_listener, 'run'): + # Set variable so that we will never run twice. + # Because the event bus might have to wait till a thread comes + # available to execute this listener it might occur that the + # listener gets lined up twice to be executed. + # This will make sure the second time it does nothing. + onetime_listener.run = True + + self.remove_listener(event_type, onetime_listener) + + listener(event) + + self.listen(event_type, onetime_listener) + def remove_listener(self, event_type, listener): """ Removes a listener of a specific event_type. """ with self._lock: @@ -487,10 +505,13 @@ class StateMachine(object): self._bus = bus self._lock = threading.Lock() - @property - def entity_ids(self): + def entity_ids(self, domain_filter=None): """ List of entity ids that are being tracked. """ - return list(self._states.keys()) + if domain_filter is not None: + return [entity_id for entity_id in self._states.keys() + if util.split_entity_id(entity_id)[0] == domain_filter] + else: + return list(self._states.keys()) def all(self): """ Returns a list of all states. """ @@ -619,14 +640,14 @@ class Timer(threading.Thread): # every minute. assert 60 % self.interval == 0, "60 % TIMER_INTERVAL should be 0!" - hass.listen_once_event(EVENT_HOMEASSISTANT_START, - lambda event: self.start()) + hass.bus.listen_once(EVENT_HOMEASSISTANT_START, + lambda event: self.start()) def run(self): """ Start the timer. """ - self.hass.listen_once_event(EVENT_HOMEASSISTANT_STOP, - lambda event: self._stop.set()) + self.hass.bus.listen_once(EVENT_HOMEASSISTANT_STOP, + lambda event: self._stop.set()) _LOGGER.info("Timer:starting") diff --git a/homeassistant/components/__init__.py b/homeassistant/components/__init__.py index a7eeadabc69..9b04d266668 100644 --- a/homeassistant/components/__init__.py +++ b/homeassistant/components/__init__.py @@ -61,7 +61,7 @@ def is_on(hass, entity_id=None): entity_ids = group.expand_entity_ids(hass, [entity_id]) else: - entity_ids = hass.states.entity_ids + entity_ids = hass.states.entity_ids() for entity_id in entity_ids: domain = util.split_entity_id(entity_id)[0] diff --git a/homeassistant/components/chromecast.py b/homeassistant/components/chromecast.py index c5b0c180d99..c7baee64496 100644 --- a/homeassistant/components/chromecast.py +++ b/homeassistant/components/chromecast.py @@ -38,7 +38,7 @@ def is_on(hass, entity_id=None): """ Returns true if specified ChromeCast entity_id is on. Will check all chromecasts if no entity_id specified. """ - entity_ids = [entity_id] if entity_id else hass.get_entity_ids(DOMAIN) + entity_ids = [entity_id] if entity_id else hass.states.entity_ids(DOMAIN) return any(not hass.states.is_state(entity_id, STATE_NO_APP) for entity_id in entity_ids) diff --git a/homeassistant/components/demo.py b/homeassistant/components/demo.py index 961feea705e..ca04d90e7fc 100644 --- a/homeassistant/components/demo.py +++ b/homeassistant/components/demo.py @@ -41,7 +41,7 @@ def setup(hass, config): if service.data and ATTR_ENTITY_ID in service.data: entity_ids = extract_entity_ids(hass, service) else: - entity_ids = hass.get_entity_ids(service.domain) + entity_ids = hass.states.entity_ids(service.domain) for entity_id in entity_ids: domain, _ = split_entity_id(entity_id) @@ -59,7 +59,7 @@ def setup(hass, config): if service.data and ATTR_ENTITY_ID in service.data: entity_ids = extract_entity_ids(hass, service) else: - entity_ids = hass.get_entity_ids(service.domain) + entity_ids = hass.states.entity_ids(service.domain) for entity_id in entity_ids: hass.states.set(entity_id, STATE_OFF) diff --git a/homeassistant/components/device_sun_light_trigger.py b/homeassistant/components/device_sun_light_trigger.py index 0fc2b99ee31..7bb1f9cbddc 100644 --- a/homeassistant/components/device_sun_light_trigger.py +++ b/homeassistant/components/device_sun_light_trigger.py @@ -36,7 +36,7 @@ def setup(hass, config): logger = logging.getLogger(__name__) - device_entity_ids = hass.get_entity_ids(device_tracker.DOMAIN) + device_entity_ids = hass.states.entity_ids(device_tracker.DOMAIN) if not device_entity_ids: logger.error("No devices found to track") diff --git a/homeassistant/components/http/__init__.py b/homeassistant/components/http/__init__.py index 79bd17044f4..0d115d95524 100644 --- a/homeassistant/components/http/__init__.py +++ b/homeassistant/components/http/__init__.py @@ -133,7 +133,7 @@ def setup(hass, config): RequestHandler, hass, api_password, development) - hass.listen_once_event( + hass.bus.listen_once( ha.EVENT_HOMEASSISTANT_START, lambda event: threading.Thread(target=server.start, daemon=True).start()) @@ -171,7 +171,7 @@ class HomeAssistantHTTPServer(ThreadingMixIn, HTTPServer): def start(self): """ Starts the server. """ - self.hass.listen_once_event( + self.hass.bus.listen_once( ha.EVENT_HOMEASSISTANT_STOP, lambda event: self.shutdown()) diff --git a/test/test_component_demo.py b/test/test_component_demo.py index 901d62b4f60..54619266078 100644 --- a/test/test_component_demo.py +++ b/test/test_component_demo.py @@ -6,9 +6,6 @@ Tests demo component. """ # pylint: disable=too-many-public-methods,protected-access import unittest -import datetime as dt - -import ephem import homeassistant as ha import homeassistant.components.demo as demo @@ -33,7 +30,7 @@ class TestDemo(unittest.TestCase): for domain in ('light', 'switch'): # Focus on 1 entity - entity_id = self.hass.get_entity_ids(domain)[0] + entity_id = self.hass.states.entity_ids(domain)[0] self.hass.call_service( domain, SERVICE_TURN_ON, {ATTR_ENTITY_ID: entity_id}) @@ -54,7 +51,7 @@ class TestDemo(unittest.TestCase): self.hass._pool.block_till_done() - for entity_id in self.hass.get_entity_ids(domain): + for entity_id in self.hass.states.entity_ids(domain): self.assertEqual( STATE_ON, self.hass.states.get(entity_id).state) @@ -62,7 +59,7 @@ class TestDemo(unittest.TestCase): self.hass._pool.block_till_done() - for entity_id in self.hass.get_entity_ids(domain): + for entity_id in self.hass.states.entity_ids(domain): self.assertEqual( STATE_OFF, self.hass.states.get(entity_id).state) diff --git a/test/test_component_group.py b/test/test_component_group.py index 2af99e3c209..80c63ae9b0c 100644 --- a/test/test_component_group.py +++ b/test/test_component_group.py @@ -44,7 +44,7 @@ class TestComponentsGroup(unittest.TestCase): """ Test setup_group method. """ # Test if group setup in our init mode is ok - self.assertIn(self.group_name, self.hass.states.entity_ids) + self.assertIn(self.group_name, self.hass.states.entity_ids()) group_state = self.hass.states.get(self.group_name) self.assertEqual(comps.STATE_ON, group_state.state) @@ -73,7 +73,7 @@ class TestComponentsGroup(unittest.TestCase): ['light.Bowl', 'device_tracker.Paulus'])) # Try to setup a group with a non existing state - self.assertNotIn('non.existing', self.hass.states.entity_ids) + self.assertNotIn('non.existing', self.hass.states.entity_ids()) self.assertFalse(group.setup_group( self.hass, 'light_and_nothing', ['light.Bowl', 'non.existing'])) diff --git a/test/test_component_http.py b/test/test_component_http.py index f4080daaa8b..2a840d39499 100644 --- a/test/test_component_http.py +++ b/test/test_component_http.py @@ -176,8 +176,6 @@ class TestHTTP(unittest.TestCase): def test_api_state_change_with_bad_data(self): """ Test if API sends appropriate error if we omit state. """ - new_state = "debug_state_change" - req = requests.post( _url(remote.URL_API_STATES_ENTITY.format( "test_entity.that_does_not_exist")), @@ -195,7 +193,7 @@ class TestHTTP(unittest.TestCase): """ Helper method that will verify our event got called. """ test_value.append(1) - hass.listen_once_event("test.event_no_data", listener) + hass.bus.listen_once("test.event_no_data", listener) requests.post( _url(remote.URL_API_EVENTS_EVENT.format("test.event_no_data")), @@ -216,7 +214,7 @@ class TestHTTP(unittest.TestCase): if "test" in event.data: test_value.append(1) - hass.listen_once_event("test_event_with_data", listener) + hass.bus.listen_once("test_event_with_data", listener) requests.post( _url(remote.URL_API_EVENTS_EVENT.format("test_event_with_data")), @@ -236,7 +234,7 @@ class TestHTTP(unittest.TestCase): """ Helper method that will verify our event got called. """ test_value.append(1) - hass.listen_once_event("test_event_bad_data", listener) + hass.bus.listen_once("test_event_bad_data", listener) req = requests.post( _url(remote.URL_API_EVENTS_EVENT.format("test_event_bad_data")), diff --git a/test/test_core.py b/test/test_core.py index d8b4e2d1283..0c046ed0cc2 100644 --- a/test/test_core.py +++ b/test/test_core.py @@ -64,17 +64,6 @@ class TestHomeAssistant(unittest.TestCase): self.assertFalse(blocking_thread.is_alive()) - def test_get_entity_ids(self): - """ Test get_entity_ids method. """ - ent_ids = self.hass.get_entity_ids() - self.assertEqual(2, len(ent_ids)) - self.assertTrue('light.Bowl' in ent_ids) - self.assertTrue('switch.AC' in ent_ids) - - ent_ids = self.hass.get_entity_ids('light') - self.assertEqual(1, len(ent_ids)) - self.assertTrue('light.Bowl' in ent_ids) - def test_track_state_change(self): """ Test track_state_change. """ # 2 lists to track how often our callbacks got called @@ -112,21 +101,6 @@ class TestHomeAssistant(unittest.TestCase): self.assertEqual(1, len(specific_runs)) self.assertEqual(3, len(wildcard_runs)) - def test_listen_once_event(self): - """ Test listen_once_event method. """ - runs = [] - - self.hass.listen_once_event('test_event', lambda x: runs.append(1)) - - self.hass.bus.fire('test_event') - self.hass._pool.block_till_done() - self.assertEqual(1, len(runs)) - - # Second time it should not increase runs - self.hass.bus.fire('test_event') - self.hass._pool.block_till_done() - self.assertEqual(1, len(runs)) - def test_track_point_in_time(self): """ Test track point in time. """ before_birthday = datetime(1985, 7, 9, 12, 0, 0) @@ -234,6 +208,21 @@ class TestEventBus(unittest.TestCase): # Try deleting listener while category doesn't exist either self.bus.remove_listener('test', listener) + def test_listen_once_event(self): + """ Test listen_once_event method. """ + runs = [] + + self.bus.listen_once('test_event', lambda x: runs.append(1)) + + self.bus.fire('test_event') + self.bus._pool.block_till_done() + self.assertEqual(1, len(runs)) + + # Second time it should not increase runs + self.bus.fire('test_event') + self.bus._pool.block_till_done() + self.assertEqual(1, len(runs)) + class TestState(unittest.TestCase): """ Test EventBus methods. """ @@ -276,11 +265,22 @@ 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_entity_ids(self): + """ Test get_entity_ids method. """ + ent_ids = self.states.entity_ids() + self.assertEqual(2, len(ent_ids)) + self.assertTrue('light.Bowl' in ent_ids) + self.assertTrue('switch.AC' in ent_ids) + + ent_ids = self.states.entity_ids('light') + self.assertEqual(1, len(ent_ids)) + self.assertTrue('light.Bowl' in ent_ids) + def test_remove(self): """ Test remove method. """ - self.assertTrue('light.Bowl' in self.states.entity_ids) + self.assertTrue('light.Bowl' in self.states.entity_ids()) self.assertTrue(self.states.remove('light.Bowl')) - self.assertFalse('light.Bowl' in self.states.entity_ids) + self.assertFalse('light.Bowl' in self.states.entity_ids()) # If it does not exist, we should get False self.assertFalse(self.states.remove('light.Bowl')) diff --git a/test/test_remote.py b/test/test_remote.py index 948a84a7600..adeeaaa8e72 100644 --- a/test/test_remote.py +++ b/test/test_remote.py @@ -96,7 +96,7 @@ class TestRemoteMethods(unittest.TestCase): """ Helper method that will verify our event got called. """ test_value.append(1) - hass.listen_once_event("test.event_no_data", listener) + hass.bus.listen_once("test.event_no_data", listener) remote.fire_event(master_api, "test.event_no_data") @@ -217,7 +217,7 @@ class TestRemoteClasses(unittest.TestCase): """ Helper method that will verify our event got called. """ test_value.append(1) - slave.listen_once_event("test.event_no_data", listener) + slave.bus.listen_once("test.event_no_data", listener) slave.bus.fire("test.event_no_data")