diff --git a/custom_components/vivint/__init__.py b/custom_components/vivint/__init__.py index 55058c6..709045c 100644 --- a/custom_components/vivint/__init__.py +++ b/custom_components/vivint/__init__.py @@ -108,16 +108,18 @@ async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): ) hub: VivintHub = hass.data[DOMAIN][entry.entry_id] - hub.remove_cache_file() - await hub.account.disconnect() - hub.undo_listener() - - if unload_ok: - hass.data[DOMAIN].pop(entry.entry_id) + await hub.disconnect() return unload_ok +async def async_remove_entry(hass: HomeAssistant, entry: ConfigEntry) -> None: + """Handle removal of an entry.""" + hub: VivintHub = hass.data[DOMAIN][entry.entry_id] + await hub.disconnect(remove_cache=True) + hass.data[DOMAIN].pop(entry.entry_id) + + async def update_listener(hass, entry: ConfigEntry): """Handle options update.""" await hass.config_entries.async_reload(entry.entry_id) diff --git a/custom_components/vivint/config_flow.py b/custom_components/vivint/config_flow.py index 79ef9c5..210b47b 100644 --- a/custom_components/vivint/config_flow.py +++ b/custom_components/vivint/config_flow.py @@ -2,19 +2,19 @@ import logging from typing import Any, Dict, Optional -import voluptuous as vol from aiohttp import ClientResponseError from aiohttp.client_exceptions import ClientConnectorError -from homeassistant import config_entries -from homeassistant.const import CONF_PASSWORD, CONF_USERNAME -from homeassistant.core import callback from vivintpy.exceptions import ( VivintSkyApiAuthenticationError, VivintSkyApiError, VivintSkyApiMfaRequiredError, ) +import voluptuous as vol + +from homeassistant import config_entries +from homeassistant.const import CONF_PASSWORD, CONF_USERNAME +from homeassistant.core import callback -from .const import DOMAIN # pylint:disable=unused-import from .const import ( CONF_HD_STREAM, CONF_MFA, @@ -23,6 +23,7 @@ DEFAULT_RTSP_STREAM, RTSP_STREAM_TYPES, ) +from .const import DOMAIN # pylint:disable=unused-import from .hub import VivintHub _LOGGER = logging.getLogger(__name__) @@ -63,6 +64,7 @@ async def async_create_entry(self): await self.hass.config_entries.async_reload(existing_entry.entry_id) return self.async_abort(reason="reauth_successful") + await self._hub.disconnect() return super().async_create_entry( title=config_data[CONF_USERNAME], data=config_data ) @@ -119,6 +121,7 @@ async def async_step_mfa(self, user_input=None): data_schema=STEP_MFA_DATA_SCHEMA, errors={"base": "unknown"}, ) + return await self.async_create_entry() async def async_step_reauth(self, user_input=None): diff --git a/custom_components/vivint/hub.py b/custom_components/vivint/hub.py index 9773a56..ed7edb0 100644 --- a/custom_components/vivint/hub.py +++ b/custom_components/vivint/hub.py @@ -46,9 +46,10 @@ def __init__( ): """Initialize the Vivint hub.""" self._data = data - self.undo_listener = undo_listener + self.__undo_listener = undo_listener self.account: Account = None self.logged_in = False + self.session: ClientSession = None async def _async_update_data(): """Update all device states from the Vivint API.""" @@ -75,11 +76,13 @@ async def login( except: _LOGGER.debug("No previous session found") + self.session = ClientSession(cookie_jar=abs_cookie_jar) + self.account = Account( username=self._data[CONF_USERNAME], password=self._data[CONF_PASSWORD], persist_session=True, - client_session=ClientSession(cookie_jar=abs_cookie_jar), + client_session=self.session, ) try: await self.account.connect( @@ -96,6 +99,18 @@ async def login( _LOGGER.error("Unable to connect to the Vivint API") raise ex + async def disconnect(self, remove_cache: bool = False) -> None: + """Disconnect from Vivint, close the session and optionally remove cache.""" + if self.account.connected: + await self.account.disconnect() + if not self.session.closed: + await self.session.close() + if remove_cache: + self.remove_cache_file() + if self.__undo_listener: + self.__undo_listener() + self.__undo_listener = None + async def verify_mfa(self, code: str): try: await self.account.verify_mfa(code) diff --git a/custom_components/vivint/manifest.json b/custom_components/vivint/manifest.json index d8cf056..7dc060b 100644 --- a/custom_components/vivint/manifest.json +++ b/custom_components/vivint/manifest.json @@ -1,11 +1,11 @@ { "domain": "vivint", "name": "Vivint", - "version": "2021.9.3", + "version": "2021.9.4", "config_flow": true, "documentation": "https://github.com/natekspencer/hacs-vivint", "issue_tracker": "https://github.com/natekspencer/hacs-vivint/issues", - "requirements": ["vivintpy==2021.9.5"], + "requirements": ["vivintpy==2021.9.7"], "dependencies": ["ffmpeg"], "codeowners": ["@natekspencer"] }