From b89209952d2ede9a3640328f4eebdbfb145db1b4 Mon Sep 17 00:00:00 2001 From: Rohan Kapoor Date: Sat, 26 Jan 2019 13:23:06 -0800 Subject: [PATCH 1/3] Embed device_tracker in gpslogger --- .../{device_tracker/gpslogger.py => gpslogger/device_tracker.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename homeassistant/components/{device_tracker/gpslogger.py => gpslogger/device_tracker.py} (100%) diff --git a/homeassistant/components/device_tracker/gpslogger.py b/homeassistant/components/gpslogger/device_tracker.py similarity index 100% rename from homeassistant/components/device_tracker/gpslogger.py rename to homeassistant/components/gpslogger/device_tracker.py From b84eb33329f13efc134addd59d9dd91cb544684e Mon Sep 17 00:00:00 2001 From: Rohan Kapoor Date: Sat, 26 Jan 2019 13:24:16 -0800 Subject: [PATCH 2/3] Load/unload gpslogger entities correctly between component and platform --- .../components/gpslogger/__init__.py | 13 +++++++--- .../components/gpslogger/device_tracker.py | 24 ++++++++++++----- tests/components/gpslogger/test_init.py | 26 ++++++++++++++++--- 3 files changed, 50 insertions(+), 13 deletions(-) diff --git a/homeassistant/components/gpslogger/__init__.py b/homeassistant/components/gpslogger/__init__.py index 4d1a5708331ecd..c15a2aeae7f649 100644 --- a/homeassistant/components/gpslogger/__init__.py +++ b/homeassistant/components/gpslogger/__init__.py @@ -15,8 +15,8 @@ from homeassistant.const import HTTP_UNPROCESSABLE_ENTITY, \ HTTP_OK, ATTR_LATITUDE, ATTR_LONGITUDE, CONF_WEBHOOK_ID from homeassistant.helpers import config_entry_flow -from homeassistant.helpers.discovery import async_load_platform from homeassistant.helpers.dispatcher import async_dispatcher_send +from homeassistant.components.device_tracker import DOMAIN as DEVICE_TRACKER _LOGGER = logging.getLogger(__name__) @@ -57,9 +57,6 @@ def _id(value: str) -> str: async def async_setup(hass, hass_config): """Set up the GPSLogger component.""" - hass.async_create_task( - async_load_platform(hass, 'device_tracker', DOMAIN, {}, hass_config) - ) return True @@ -103,12 +100,20 @@ async def async_setup_entry(hass, entry): """Configure based on config entry.""" hass.components.webhook.async_register( DOMAIN, 'GPSLogger', entry.data[CONF_WEBHOOK_ID], handle_webhook) + + hass.async_create_task( + hass.config_entries.async_forward_entry_setup(entry, DEVICE_TRACKER) + ) return True async def async_unload_entry(hass, entry): """Unload a config entry.""" hass.components.webhook.async_unregister(entry.data[CONF_WEBHOOK_ID]) + + hass.async_create_task( + hass.config_entries.async_forward_entry_unload(entry, DEVICE_TRACKER) + ) return True config_entry_flow.register_webhook_flow( diff --git a/homeassistant/components/gpslogger/device_tracker.py b/homeassistant/components/gpslogger/device_tracker.py index e0d9b37bf84e04..8a312afa024817 100644 --- a/homeassistant/components/gpslogger/device_tracker.py +++ b/homeassistant/components/gpslogger/device_tracker.py @@ -6,18 +6,22 @@ """ import logging -from homeassistant.components.gpslogger import TRACKER_UPDATE +from homeassistant.components.device_tracker import DOMAIN as \ + DEVICE_TRACKER_DOMAIN +from homeassistant.components.gpslogger import DOMAIN as GPSLOGGER_DOMAIN, \ + TRACKER_UPDATE from homeassistant.helpers.dispatcher import async_dispatcher_connect -from homeassistant.helpers.typing import HomeAssistantType, ConfigType +from homeassistant.helpers.typing import HomeAssistantType _LOGGER = logging.getLogger(__name__) DEPENDENCIES = ['gpslogger'] +DATA_KEY = '{}.{}'.format(GPSLOGGER_DOMAIN, DEVICE_TRACKER_DOMAIN) -async def async_setup_scanner(hass: HomeAssistantType, config: ConfigType, - async_see, discovery_info=None): - """Set up an endpoint for the GPSLogger device tracker.""" + +async def async_setup_entry(hass: HomeAssistantType, entry, async_see): + """Configure a dispatcher connection based on a config entry.""" async def _set_location(device, gps_location, battery, accuracy, attrs): """Fire HA event to set location.""" await async_see( @@ -28,5 +32,13 @@ async def _set_location(device, gps_location, battery, accuracy, attrs): attributes=attrs ) - async_dispatcher_connect(hass, TRACKER_UPDATE, _set_location) + hass.data[DATA_KEY] = async_dispatcher_connect( + hass, TRACKER_UPDATE, _set_location + ) + return True + + +async def async_unload_entry(hass: HomeAssistantType, entry): + """Unload the config entry and remove the dispatcher connection.""" + hass.data[DATA_KEY]() return True diff --git a/tests/components/gpslogger/test_init.py b/tests/components/gpslogger/test_init.py index cf818e54911f60..db1ae655c2583c 100644 --- a/tests/components/gpslogger/test_init.py +++ b/tests/components/gpslogger/test_init.py @@ -2,15 +2,17 @@ from unittest.mock import patch, Mock import pytest +from homeassistant.helpers.dispatcher import DATA_DISPATCHER from homeassistant import data_entry_flow -from homeassistant.components import zone +from homeassistant.components import zone, gpslogger from homeassistant.components.device_tracker import \ DOMAIN as DEVICE_TRACKER_DOMAIN -from homeassistant.components.gpslogger import DOMAIN +from homeassistant.components.gpslogger import DOMAIN, TRACKER_UPDATE from homeassistant.const import HTTP_OK, HTTP_UNPROCESSABLE_ENTITY, \ - STATE_HOME, STATE_NOT_HOME + STATE_HOME, STATE_NOT_HOME, CONF_WEBHOOK_ID from homeassistant.setup import async_setup_component +from tests.common import MockConfigEntry HOME_LATITUDE = 37.239622 HOME_LONGITUDE = -115.815811 @@ -164,3 +166,21 @@ async def test_enter_with_attrs(hass, gpslogger_client, webhook_id): assert 102.0 == state.attributes['altitude'] assert 'gps' == state.attributes['provider'] assert 'running' == state.attributes['activity'] + + +@pytest.mark.xfail( + reason='The device_tracker component does not support unloading yet.' +) +async def test_load_unload_entry(hass): + """Test that the appropriate dispatch signals are added and removed.""" + entry = MockConfigEntry(domain=DOMAIN, data={ + CONF_WEBHOOK_ID: 'gpslogger_test' + }) + + await gpslogger.async_setup_entry(hass, entry) + await hass.async_block_till_done() + assert 1 == len(hass.data[DATA_DISPATCHER][TRACKER_UPDATE]) + + await gpslogger.async_unload_entry(hass, entry) + await hass.async_block_till_done() + assert 0 == len(hass.data[DATA_DISPATCHER][TRACKER_UPDATE]) From b480564c3042c438fd136353a7afcca5e7d85d4d Mon Sep 17 00:00:00 2001 From: Rohan Kapoor Date: Sun, 27 Jan 2019 11:27:11 -0800 Subject: [PATCH 3/3] Await the coroutine directly --- homeassistant/components/gpslogger/__init__.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/homeassistant/components/gpslogger/__init__.py b/homeassistant/components/gpslogger/__init__.py index c15a2aeae7f649..d4150900223061 100644 --- a/homeassistant/components/gpslogger/__init__.py +++ b/homeassistant/components/gpslogger/__init__.py @@ -111,9 +111,7 @@ async def async_unload_entry(hass, entry): """Unload a config entry.""" hass.components.webhook.async_unregister(entry.data[CONF_WEBHOOK_ID]) - hass.async_create_task( - hass.config_entries.async_forward_entry_unload(entry, DEVICE_TRACKER) - ) + await hass.config_entries.async_forward_entry_unload(entry, DEVICE_TRACKER) return True config_entry_flow.register_webhook_flow(